<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Mac Operations</title>
	<atom:link href="http://macops.ca/feed/" rel="self" type="application/rss+xml" />
	<link>http://macops.ca</link>
	<description></description>
	<lastBuildDate>Tue, 16 Apr 2013 15:01:52 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Java 7: How not to use launchd for your app</title>
		<link>http://macops.ca/java-7-how-not-to-use-launchd-for-your-app/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=java-7-how-not-to-use-launchd-for-your-app</link>
		<comments>http://macops.ca/java-7-how-not-to-use-launchd-for-your-app/#comments</comments>
		<pubDate>Fri, 15 Mar 2013 22:03:06 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[launchd]]></category>
		<category><![CDATA[Sparkle]]></category>

		<guid isPermaLink="false">http://macops.ca/?p=418</guid>
		<description><![CDATA[The Oracle Java 7 package contains launchd items to support its Sparkle-based background update check app that I complained about previously. In this post we&#8217;ll go through its logic exhaustively and use it as an example of how to not deploy a LaunchAgent, and issues when trying clever things in LaunchDaemon scripts. For some, there [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://macops.ca/wp-content/uploads/2013/03/JavaCupLogo-161.png"><img src="http://macops.ca/wp-content/uploads/2013/03/JavaCupLogo-161.png" alt="JavaCupLogo-161_tint" width="81" height="162" class="alignleft size-full wp-image-460" /></a>The Oracle Java 7 package contains launchd items to support its Sparkle-based background update check app that I complained about previously. In this post we&#8217;ll go through its logic exhaustively and use it as an example of how to not deploy a LaunchAgent, and issues when trying clever things in LaunchDaemon scripts.</p>
<p>For some, there should be new information about how launchd works in general, as I think for many admins its behavior is somewhat opaque. Along the way I also learned some new launchctl command options.</p>
<p><span id="more-418"></span></p>
<h3>Introducing &#8216;Helper-Tool&#8217;</h3>
<p>First, let&#8217;s paste the entire <code class="codecolorer text solarized-light"><span class="text">Helper-Tool</span></code> script, and go through it. This is called by the <code class="codecolorer text solarized-light"><span class="text">com.oracle.java.Helper-Tool</span></code> LaunchDaemon, and is triggered whenever the <code class="codecolorer text solarized-light"><span class="text">com.oracle.java.Java-Plugin</span></code> LaunchAgent plist (which is actually a symlink to a plist in the plugin&#8217;s <code class="codecolorer text solarized-light"><span class="text">Contents/Resources</span></code> directory) is modified.</p>
<div class="codecolorer-container bash solarized-light" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br /></div></td><td><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666; font-style: italic;">#!/bin/bash</span><br />
<span style="color: #666666; font-style: italic;"># This is a specialized randomizer function</span><br />
<span style="color: #666666; font-style: italic;"># that will randomize when AU will be triggered</span><br />
<span style="color: #666666; font-style: italic;"># for sceduled updates for a Mac</span><br />
rand<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#123;</span><br />
&nbsp; <span style="color: #7a0874; font-weight: bold;">local</span> <span style="color: #007800;">max_value</span>=<span style="color: #ff0000;">&quot;$1&quot;</span><br />
&nbsp; <span style="color: #007800;">n</span>=<span style="color: #007800;">$RANDOM</span><br />
&nbsp; <span style="color: #007800;">var</span>=$<span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #000000;">1</span> + <span style="color: #007800;">$n</span> <span style="color: #000000; font-weight: bold;">%</span> <span style="color: #007800;">$max_value</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span><br />
&nbsp; <span style="color: #007800;">retValue</span>=<span style="color: #007800;">$var</span><br />
<span style="color: #7a0874; font-weight: bold;">&#125;</span><br />
<br />
<span style="color: #666666; font-style: italic;"># Make the appropriate Changes to plist file post-AU if the com.oracle.java.Java-Updater.plist is changed</span><br />
<span style="color: #666666; font-style: italic;">#Get the stored value of preferences</span><br />
<span style="color: #007800;">HTHOUR</span>=<span style="color: #000000; font-weight: bold;">`</span>defaults <span style="color: #c20cb9; font-weight: bold;">read</span> <span style="color: #000000; font-weight: bold;">/</span>Library<span style="color: #000000; font-weight: bold;">/</span>Preferences<span style="color: #000000; font-weight: bold;">/</span>com.oracle.java.Helper-Tool HTHour <span style="color: #000000;">2</span><span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null<span style="color: #000000; font-weight: bold;">`</span><br />
<span style="color: #007800;">HTMINUTE</span>=<span style="color: #000000; font-weight: bold;">`</span>defaults <span style="color: #c20cb9; font-weight: bold;">read</span> <span style="color: #000000; font-weight: bold;">/</span>Library<span style="color: #000000; font-weight: bold;">/</span>Preferences<span style="color: #000000; font-weight: bold;">/</span>com.oracle.java.Helper-Tool HTMinute <span style="color: #000000;">2</span><span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null<span style="color: #000000; font-weight: bold;">`</span><br />
<span style="color: #007800;">HTWEEKDAY</span>=<span style="color: #000000; font-weight: bold;">`</span>defaults <span style="color: #c20cb9; font-weight: bold;">read</span> <span style="color: #000000; font-weight: bold;">/</span>Library<span style="color: #000000; font-weight: bold;">/</span>Preferences<span style="color: #000000; font-weight: bold;">/</span>com.oracle.java.Helper-Tool HTWeekday <span style="color: #000000;">2</span><span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null<span style="color: #000000; font-weight: bold;">`</span><br />
<span style="color: #666666; font-style: italic;"># Constants</span><br />
<span style="color: #007800;">LAUNCHD_PLIST_SRC</span>=<span style="color: #000000; font-weight: bold;">/</span>Library<span style="color: #000000; font-weight: bold;">/</span>Internet\ Plug-Ins<span style="color: #000000; font-weight: bold;">/</span>JavaAppletPlugin.plugin<span style="color: #000000; font-weight: bold;">/</span>Contents<span style="color: #000000; font-weight: bold;">/</span>Resources<span style="color: #000000; font-weight: bold;">/</span>com.oracle.java.Java-Updater.plist<br />
<span style="color: #007800;">LAUNCHD_PLIST_DEST</span>=<span style="color: #000000; font-weight: bold;">/</span>Library<span style="color: #000000; font-weight: bold;">/</span>LaunchAgents<span style="color: #000000; font-weight: bold;">/</span><br />
<span style="color: #007800;">LAUNCHD_PLIST_NAME</span>=com.oracle.java.Java-Updater.plist<br />
<span style="color: #666666; font-style: italic;"># Commands</span><br />
<span style="color: #007800;">PLISTBUDDY</span>=<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>libexec<span style="color: #000000; font-weight: bold;">/</span>PListBuddy<br />
<span style="color: #007800;">SED</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">which</span> <span style="color: #c20cb9; font-weight: bold;">sed</span><span style="color: #000000; font-weight: bold;">`</span><br />
<span style="color: #007800;">CHMOD</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">which</span> <span style="color: #c20cb9; font-weight: bold;">chmod</span><span style="color: #000000; font-weight: bold;">`</span><br />
<span style="color: #007800;">LAUNCHCTL</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">which</span> launchctl<span style="color: #000000; font-weight: bold;">`</span><br />
<br />
<span style="color: #666666; font-style: italic;"># Values</span><br />
<span style="color: #007800;">HOUR_VALUE</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">date</span> +<span style="color: #000000; font-weight: bold;">%</span>H<span style="color: #000000; font-weight: bold;">`</span><br />
<span style="color: #007800;">MINUTE_VALUE</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">date</span> +<span style="color: #000000; font-weight: bold;">%</span>M<span style="color: #000000; font-weight: bold;">`</span><br />
<br />
<span style="color: #666666; font-style: italic;"># If defaults are already set then over-write with defaults. Else Randomize</span><br />
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">${HTHOUR}</span>&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #000000; font-weight: bold;">||</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">${HTMINUTE}</span>&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #000000; font-weight: bold;">||</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">${HTWEEKDAY}</span>&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span><br />
&nbsp; &nbsp; rand <span style="color: #000000;">7</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #800000;">${SED}</span> <span style="color: #660033;">-i</span> <span style="color: #ff0000;">&quot;&quot;</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">&quot;s/2/<span style="color: #007800;">${retValue}</span>/g&quot;</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">&quot;s/00/<span style="color: #007800;">${MINUTE_VALUE}</span>/g&quot;</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">&quot;s/09/<span style="color: #007800;">${HOUR_VALUE}</span>/g&quot;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">${LAUNCHD_PLIST_SRC}</span>&quot;</span><br />
<span style="color: #000000; font-weight: bold;">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #800000;">${PLISTBUDDY}</span> <span style="color: #660033;">-c</span> <span style="color: #ff0000;">&quot;Set :StartCalendarInterval:Hour '<span style="color: #007800;">${HTHOUR}</span>'&quot;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">${LAUNCHD_PLIST_SRC}</span>&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #800000;">${PLISTBUDDY}</span> <span style="color: #660033;">-c</span> <span style="color: #ff0000;">&quot;Set :StartCalendarInterval:Minute '<span style="color: #007800;">${HTMINUTE}</span>'&quot;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">${LAUNCHD_PLIST_SRC}</span>&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #800000;">${PLISTBUDDY}</span> <span style="color: #660033;">-c</span> <span style="color: #ff0000;">&quot;Set :StartCalendarInterval:Weekday '<span style="color: #007800;">${HTWEEKDAY}</span>'&quot;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">${LAUNCHD_PLIST_SRC}</span>&quot;</span><br />
<span style="color: #000000; font-weight: bold;">fi</span><br />
<span style="color: #800000;">${CHMOD}</span> <span style="color: #000000;">644</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">${LAUNCHD_PLIST_SRC}</span>&quot;</span><br />
<span style="color: #800000;">${LAUNCHCTL}</span> unload <span style="color: #ff0000;">&quot;<span style="color: #007800;">${LAUNCHD_PLIST_DEST}</span>/<span style="color: #007800;">${LAUNCHD_PLIST_NAME}</span>&quot;</span><br />
<span style="color: #800000;">${LAUNCHCTL}</span> load <span style="color: #ff0000;">&quot;<span style="color: #007800;">${LAUNCHD_PLIST_DEST}</span>/<span style="color: #007800;">${LAUNCHD_PLIST_NAME}</span>&quot;</span></div></td></tr></tbody></table></div>
<p>According to the comments, as we suspected, the purpose of this is to &#8220;Make the appropriate Changes&#8221; to the LaunchAgent plist following an update.</p>
<div class="codecolorer-container bash solarized-light" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #007800;">HTHOUR</span>=<span style="color: #000000; font-weight: bold;">`</span>defaults <span style="color: #c20cb9; font-weight: bold;">read</span> <span style="color: #000000; font-weight: bold;">/</span>Library<span style="color: #000000; font-weight: bold;">/</span>Preferences<span style="color: #000000; font-weight: bold;">/</span>com.oracle.java.Helper-Tool HTHour <span style="color: #000000;">2</span><span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null<span style="color: #000000; font-weight: bold;">`</span><br />
<span style="color: #007800;">HTMINUTE</span>=<span style="color: #000000; font-weight: bold;">`</span>defaults <span style="color: #c20cb9; font-weight: bold;">read</span> <span style="color: #000000; font-weight: bold;">/</span>Library<span style="color: #000000; font-weight: bold;">/</span>Preferences<span style="color: #000000; font-weight: bold;">/</span>com.oracle.java.Helper-Tool HTMinute <span style="color: #000000;">2</span><span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null<span style="color: #000000; font-weight: bold;">`</span><br />
<span style="color: #007800;">HTWEEKDAY</span>=<span style="color: #000000; font-weight: bold;">`</span>defaults <span style="color: #c20cb9; font-weight: bold;">read</span> <span style="color: #000000; font-weight: bold;">/</span>Library<span style="color: #000000; font-weight: bold;">/</span>Preferences<span style="color: #000000; font-weight: bold;">/</span>com.oracle.java.Helper-Tool HTWeekday <span style="color: #000000;">2</span><span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>dev<span style="color: #000000; font-weight: bold;">/</span>null<span style="color: #000000; font-weight: bold;">`</span></div></div>
<p>Reading some preference values that were set by the installer postinstall script, suppressing error output in case the keys didn&#8217;t exist. Ok.</p>
<div class="codecolorer-container bash solarized-light" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666; font-style: italic;"># Commands</span><br />
<span style="color: #007800;">PLISTBUDDY</span>=<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>libexec<span style="color: #000000; font-weight: bold;">/</span>PListBuddy<br />
<span style="color: #007800;">SED</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">which</span> <span style="color: #c20cb9; font-weight: bold;">sed</span><span style="color: #000000; font-weight: bold;">`</span><br />
<span style="color: #007800;">CHMOD</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">which</span> <span style="color: #c20cb9; font-weight: bold;">chmod</span><span style="color: #000000; font-weight: bold;">`</span><br />
<span style="color: #007800;">LAUNCHCTL</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">which</span> launchctl<span style="color: #000000; font-weight: bold;">`</span></div></div>
<p>Two problems. One, &#8216;/usr/libexec/PListbuddy&#8217; is a typo. It just goes unchecked because probably 99.9% of OS X systems are on a case-insensitive HFS+ filesystem, but OS X fully supports installation onto case-sensitive filesystems.</p>
<p>Two, defining commands&#8217; absolute paths using `which command` is useless. The <code class="codecolorer text solarized-light"><span class="text">which</span></code> command works by searching the PATH environment variable for the executable. If you depend on being able to locate an executable by `which` in your script, you can skip pretending you&#8217;re using absolute paths, because you&#8217;ve already assumed they&#8217;ll be located in your PATH. You can get the default PATH used by launchd with the command: <code class="codecolorer text solarized-light"><span class="text">launchctl getenv PATH</span></code>.</p>
<div class="codecolorer-container bash solarized-light" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666; font-style: italic;"># Values</span><br />
<span style="color: #007800;">HOUR_VALUE</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">date</span> +<span style="color: #000000; font-weight: bold;">%</span>H<span style="color: #000000; font-weight: bold;">`</span><br />
<span style="color: #007800;">MINUTE_VALUE</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">date</span> +<span style="color: #000000; font-weight: bold;">%</span>M<span style="color: #000000; font-weight: bold;">`</span><br />
<br />
<span style="color: #666666; font-style: italic;"># If defaults are already set then over-write with defaults. Else Randomize</span><br />
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">${HTHOUR}</span>&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #000000; font-weight: bold;">||</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">${HTMINUTE}</span>&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #000000; font-weight: bold;">||</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">${HTWEEKDAY}</span>&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span><br />
&nbsp; &nbsp; rand <span style="color: #000000;">7</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #800000;">${SED}</span> <span style="color: #660033;">-i</span> <span style="color: #ff0000;">&quot;&quot;</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">&quot;s/2/<span style="color: #007800;">${retValue}</span>/g&quot;</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">&quot;s/00/<span style="color: #007800;">${MINUTE_VALUE}</span>/g&quot;</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">&quot;s/09/<span style="color: #007800;">${HOUR_VALUE}</span>/g&quot;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">${LAUNCHD_PLIST_SRC}</span>&quot;</span><br />
<span style="color: #000000; font-weight: bold;">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #800000;">${PLISTBUDDY}</span> <span style="color: #660033;">-c</span> <span style="color: #ff0000;">&quot;Set :StartCalendarInterval:Hour '<span style="color: #007800;">${HTHOUR}</span>'&quot;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">${LAUNCHD_PLIST_SRC}</span>&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #800000;">${PLISTBUDDY}</span> <span style="color: #660033;">-c</span> <span style="color: #ff0000;">&quot;Set :StartCalendarInterval:Minute '<span style="color: #007800;">${HTMINUTE}</span>'&quot;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">${LAUNCHD_PLIST_SRC}</span>&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #800000;">${PLISTBUDDY}</span> <span style="color: #660033;">-c</span> <span style="color: #ff0000;">&quot;Set :StartCalendarInterval:Weekday '<span style="color: #007800;">${HTWEEKDAY}</span>'&quot;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">${LAUNCHD_PLIST_SRC}</span>&quot;</span><br />
<span style="color: #000000; font-weight: bold;">fi</span></div></div>
<p>If any of the <code class="codecolorer text solarized-light"><span class="text">HT</span></code> variables are undefined (<code class="codecolorer text solarized-light"><span class="text">-z</span></code> tests for a zero-length string), then store a random value in <code class="codecolorer text solarized-light"><span class="text">retValue</span></code>, and use the sed command to perform an inline replace it in the plist.</p>
<p>One might ask, if this system is designed specifically to &#8220;reset&#8221; the LaunchAgent schedule after an update, why not simply put this logic into a postinstall script instead, and set the schedule to something like once per day?</p>
<p>Using sed to modify a plist is just silly. Plists are structured data, and there are tools, like PlistBuddy used in the following three lines, that were made for exactly this. The <code class="codecolorer text solarized-light"><span class="text">00</span></code> minute and <code class="codecolorer text solarized-light"><span class="text">09</span></code> hour values correspond to the values that were already in the LaunchAgent plist delivered by the installer payload. This sed command is also already performed by the installer script.</p>
<p>Despite all of these silly workarounds to update a schedule plist, there are also weak assumptions in the if statement:</p>
<ul>
<li>If any of the HT* variables stored in <code class="codecolorer text solarized-light"><span class="text">com.oracle.java.Helper-Tool</span></code> by the installer don&#8217;t exist, then it must be able to find exactly these stock <code class="codecolorer text solarized-light"><span class="text">StartCalendarInterval</span></code> times in the <code class="codecolorer text solarized-light"><span class="text">com.oracle.java.Java-Updater</span></code> plist, and that these wouldn&#8217;t somehow conflict with numerical values elsewhere in the plist (we&#8217;ll see later that if one enables debugging for this LaunchAgent, it will).</li>
<li>Two, PlistBuddy&#8217;s &#8216;Set&#8217; command requires the key to already exist &#8211; it does not add a missing key as with the &#8216;defaults&#8217; command. The logic used by this if statement is vague, because it&#8217;s assuming that if any one key in one domain <code class="codecolorer text solarized-light"><span class="text">com.oracle.java.Helper-Tool</span></code> is missing, then we must be able to find all three of some other key in a different plist <code class="codecolorer text solarized-light"><span class="text">com.oracle.java.Java-Updater</span></code>.</li>
</ul>
<p>What&#8217;s worse, is that by littering these various preference domains with various keys that all seem to be related to a schedule but only coupled by flawed scripts, admins that may poke at these values attempting to shortcircuit its update check behaviour may just further confuse the roundabout logic used in these scripts. Of course, vendors don&#8217;t design their packages with poking in mind, but given that this concerns behaviour that most system administrators will immediately want to <em>disable</em>, it doesn&#8217;t help to make it as difficult as possible to disable something that&#8217;s usually trivial with other software, something even <em>Adobe</em> can document and support.</p>
<p>Continuing on&#8230;</p>
<div class="codecolorer-container bash solarized-light" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #800000;">${CHMOD}</span> <span style="color: #000000;">644</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">${LAUNCHD_PLIST_SRC}</span>&quot;</span></div></div>
<p>Why would this be necessary? Permissions should be normally only handled by the installer payload, except in very particular circumstances that can usually be avoided. Maybe it&#8217;s here because the permissions are actually <em>wrong</em> (mode 664, when they should be mode 644) in the installer&#8217;s payloads for both launchd plists.</p>
<h3>launchd and Session Types</h3>
<div class="codecolorer-container bash solarized-light" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #800000;">${LAUNCHCTL}</span> unload <span style="color: #ff0000;">&quot;<span style="color: #007800;">${LAUNCHD_PLIST_DEST}</span>/<span style="color: #007800;">${LAUNCHD_PLIST_NAME}</span>&quot;</span><br />
<span style="color: #800000;">${LAUNCHCTL}</span> load <span style="color: #ff0000;">&quot;<span style="color: #007800;">${LAUNCHD_PLIST_DEST}</span>/<span style="color: #007800;">${LAUNCHD_PLIST_NAME}</span>&quot;</span></div></div>
<p>This brings us to the topic of launchd and &#8220;Session Types&#8221;. LaunchDaemons and LaunchAgents can run in several different Session Types &#8211; for example, the &#8216;Aqua&#8217; Session Type is run in the context of a user that is currently logged in at the GUI. You may have noticed before that when manually loading and unloading jobs, that you need to be root in order to manage jobs that are running at the system level, for example LaunchDaemons located in <code class="codecolorer text solarized-light"><span class="text">/Library/LaunchDaemons</span></code>.</p>
<p>&#8216;LoginWindow&#8217; is another Session Type that can be specified if a job should be loaded only while the system is at the login window. The <code class="codecolorer text solarized-light"><span class="text">LimitLoadToSessionType</span></code> key can be specified in a launchd plist to restrict in which Session Types it would normally be loaded, but using the &#8216;launchctl&#8217; command permits the job to be loaded in other contexts. If <code class="codecolorer text solarized-light"><span class="text">LimitLoadToSessionType</span></code> is omitted, then the default of <code class="codecolorer text solarized-light"><span class="text">Aqua</span></code> is used. So in a normal scenario:</p>
<ol>
<li>Machine boots up, and loads the loginwindow.</li>
<li>LaunchAgents that are able to run in the LoginWindow context are loaded.</li>
<li>User logs in.</li>
<li>Jobs running in the LoginWindow Session Type are unloaded, and the jobs available to run in the Aqua Session Type as the regular user are loaded.</li>
</ol>
<p>There&#8217;s a lot more in-depth and lower-level detail available in Apple&#8217;s <a href="http://developer.apple.com/library/mac/#technotes/tn2083/_index.html#//apple_ref/doc/uid/DTS10003794-CH1-SUBSECTION10">Daemons and Agents Tech Note</a>. It&#8217;s over five years old, however.</p>
<p>In most if not all cases, if the machine was asleep when the <code class="codecolorer text solarized-light"><span class="text">StartCalendarInterval</span></code> time arrived, the job will run immediately upon waking. Even if the LaunchAgent job was somehow being loaded at the loginwindow (remember, this is to launch the Java Updater app), it would simply die and complain that no connection to the window server was possible. Actually, for this package, it <em>won&#8217;t</em>, because the job&#8217;s <code class="codecolorer text solarized-light"><span class="text">StandardErrorPath</span></code> is set to <code class="codecolorer text solarized-light"><span class="text">/dev/null</span></code>. More on that later.</p>
<p>But since Helper-Tool is running as root, its invocation of launchctl will load the job as root, and now, guess what? We have two separate instances of the LaunchAgent running. What do you think happens when the <code class="codecolorer text solarized-light"><span class="text">StartCalendarInterval</span></code> time arrives?</p>
<div id="attachment_419" class="wp-caption alignnone" style="width: 724px"><a href="http://macops.ca/wp-content/uploads/2013/02/multiple-java-updaters.png"><img src="http://macops.ca/wp-content/uploads/2013/02/multiple-java-updaters.png" alt="I don&#039;t think LSMultipleInstancesProhibited is helping here." width="714" height="770" class="size-full wp-image-419" /></a><p class="wp-caption-text">LSMultipleInstancesProhibited doesn&#8217;t prevent it the app from running as multiple users!</p></div>
<p>So now Java Updater is being run <em>twice</em>, once as you and once as root. The <code class="codecolorer text solarized-light"><span class="text">LSMultipleInstancesProhibited</span></code> would prevent it from launching twice as a user (perhaps to prevent runs over weeks on an idle system from spawning the alert multiple times?), but it won&#8217;t help here, when the alert is being launched as different users. Moreover, depending on how long the machine has been running without a reboot, there may be some time during which the job is running with two different times set in <code class="codecolorer text solarized-light"><span class="text">StartCalendarInterval</span></code>.</p>
<p>Because Java Updater uses Sparkle, selecting &#8220;Skip this version&#8221; will set the <code class="codecolorer text solarized-light"><span class="text">SUSkippedVersion</span></code> key in the app domain being used, which in this case is <code class="codecolorer text solarized-light"><span class="text">com.oracle.java.JavaAppletPlugin</span></code>. The version is as it is defined in the Sparkle XML feed (which may or may not be equal to a bundle version key). Because it&#8217;s running as two different users, these Sparkle-related preference keys are now defined in two different user homes. In other words, skipping a version as a normal user means that it will still run again as root, until it&#8217;s skipped when it launches as root. (For what it&#8217;s worth, these Sparkle preferences can be defined at the system level, but managing <code class="codecolorer text solarized-light"><span class="text">SUSkippedVersion</span></code> keys for this application gets to be a very tedious game of catch-up, and is not at all how the key is intended to be used).</p>
<p>Just to be sure that this is really happening, here&#8217;s the output of <a href="http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man1/execsnoop.1m.html"><code class="codecolorer text solarized-light"><span class="text">execsnoop</span></code></a>, a DTrace utility that logs new processes as they occur. Notice the first execution is UID 0 (root) with a PPID (parent process ID) of 1, and the second is 501 (me) and a PPID of 329. The PPIDs correspond to the launchd manager process for the System and my user&#8217;s bootstrap namespace. (You can check these yourself with the <code class="codecolorer text solarized-light"><span class="text">launchctl managerpid</span></code> command.)</p>
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">sudo execsnoop -a<br />
<br />
TIME &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; STRTIME &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PROJ &nbsp; UID &nbsp; &nbsp;PID &nbsp; PPID ARGS<br />
63549084439 &nbsp; &nbsp;2013 Mar &nbsp;8 20:14:00 &nbsp; &nbsp; 0 &nbsp; &nbsp; 0 &nbsp;25320 &nbsp; &nbsp; &nbsp;1 Java Updater<br />
63549107082 &nbsp; &nbsp;2013 Mar &nbsp;8 20:14:00 &nbsp; &nbsp; 0 &nbsp; 501 &nbsp;25321 &nbsp; &nbsp;329 Java Updater</div></div>
<p>This relaunching-as-root issue is moot once the Mac reboots, of course, because then the LaunchAgent will load only in the user&#8217;s Aqua context as usual. But with laptops, it&#8217;s not uncommon to go for weeks without a reboot, which is about how frequently there have been recent security updates are being released.</p>
<h3>No logging</h3>
<p>I mentioned earlier that the LaunchAgent&#8217;s <code class="codecolorer text solarized-light"><span class="text">StandardOutPath</span></code> and <code class="codecolorer text solarized-light"><span class="text">StandardErrorPath</span></code> are both set to <code class="codecolorer text solarized-light"><span class="text">/dev/null</span></code>. You&#8217;re free to run the Java Updater binary yourself to mimic what would happen at the time the LaunchAgent job would run, but there&#8217;s not much useful output. There&#8217;s also a debug flag you can set in your shell environment if you&#8217;d like to see a bit more: set the <code class="codecolorer text solarized-light"><span class="text">JPI_PLUGIN2_DEBUG</span></code> flag to something (it can be anything, it just must be set): <code class="codecolorer text solarized-light"><span class="text">export JPI_PLUGIN2_DEBUG=1</span></code>. You&#8217;ll then see some output like this if you run it manually:</p>
<div class="codecolorer-container bash solarized-light" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>Library<span style="color: #000000; font-weight: bold;">/</span>Internet\ Plug-Ins<span style="color: #000000; font-weight: bold;">/</span>JavaAppletPlugin.plugin<span style="color: #000000; font-weight: bold;">/</span>Contents<span style="color: #000000; font-weight: bold;">/</span>Resources<span style="color: #000000; font-weight: bold;">/</span>Java\ Updater.app<span style="color: #000000; font-weight: bold;">/</span>Contents<span style="color: #000000; font-weight: bold;">/</span>MacOS<br />
.<span style="color: #000000; font-weight: bold;">/</span>Java\ Updater<br />
<br />
<span style="color: #000000;">2013</span>-03-08 <span style="color: #000000;">21</span>:<span style="color: #000000;">56</span>:<span style="color: #000000;">08.177</span> Java Updater<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">27026</span>:<span style="color: #000000;">507</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> Found bundle at NSBundle <span style="color: #000000; font-weight: bold;">&lt;/</span>Library<span style="color: #000000; font-weight: bold;">/</span>Internet Plug-Ins<span style="color: #000000; font-weight: bold;">/</span>JavaAppletPlugin.plugin<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #7a0874; font-weight: bold;">&#40;</span>not yet loaded<span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
<span style="color: #000000;">2013</span>-03-08 <span style="color: #000000;">21</span>:<span style="color: #000000;">56</span>:<span style="color: #000000;">08.179</span> Java Updater<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">27026</span>:<span style="color: #000000;">507</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> Current bundle version = 1.7.13.20<br />
<span style="color: #000000;">2013</span>-03-08 <span style="color: #000000;">21</span>:<span style="color: #000000;">56</span>:<span style="color: #000000;">08.543</span> Java Updater<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">27026</span>:<span style="color: #000000;">507</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> updater:didFinishLoadingAppcast:<br />
<span style="color: #000000;">2013</span>-03-08 <span style="color: #000000;">21</span>:<span style="color: #000000;">56</span>:<span style="color: #000000;">08.544</span> Java Updater<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">27026</span>:<span style="color: #000000;">507</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> appcast = <span style="color: #000000; font-weight: bold;">&lt;</span>SUAppcast: 0x7fca7a441ee0<span style="color: #000000; font-weight: bold;">&gt;</span><br />
<span style="color: #000000;">2013</span>-03-08 <span style="color: #000000;">21</span>:<span style="color: #000000;">56</span>:<span style="color: #000000;">08.545</span> Java Updater<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">27026</span>:<span style="color: #000000;">507</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> updater:didFindValidUpdate:<br />
<span style="color: #000000;">2013</span>-03-08 <span style="color: #000000;">21</span>:<span style="color: #000000;">56</span>:<span style="color: #000000;">08.545</span> Java Updater<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">27026</span>:<span style="color: #000000;">507</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> item = <span style="color: #000000; font-weight: bold;">&lt;</span>SUAppcastItem: 0x7fca7a45e430<span style="color: #000000; font-weight: bold;">&gt;</span><br />
<span style="color: #000000;">2013</span>-03-08 <span style="color: #000000;">21</span>:<span style="color: #000000;">56</span>:<span style="color: #000000;">08.545</span> Java Updater<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">27026</span>:<span style="color: #000000;">507</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> URL = http:<span style="color: #000000; font-weight: bold;">//</span>javadl.sun.com<span style="color: #000000; font-weight: bold;">/</span>webapps<span style="color: #000000; font-weight: bold;">/</span>download<span style="color: #000000; font-weight: bold;">/</span>GetFile<span style="color: #000000; font-weight: bold;">/</span>1.7.0_17-b02<span style="color: #000000; font-weight: bold;">/</span>unix-i586<span style="color: #000000; font-weight: bold;">/</span>jre-7u17-fcs-bin-b02-macosx-x86_64-01_mar_2013_au.dmg<br />
<span style="color: #000000;">2013</span>-03-08 <span style="color: #000000;">21</span>:<span style="color: #000000;">56</span>:<span style="color: #000000;">08.545</span> Java Updater<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">27026</span>:<span style="color: #000000;">507</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> title = Version 1.7.0_17 <span style="color: #7a0874; font-weight: bold;">&#40;</span>build b02<span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
<span style="color: #000000;">2013</span>-03-08 <span style="color: #000000;">21</span>:<span style="color: #000000;">56</span>:<span style="color: #000000;">10.079</span> Java Updater<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">27026</span>:<span style="color: #000000;">507</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> Finished update attempt</div></div>
<p>So if we&#8217;d like to actually debug and log the behavior of the LaunchAgent itself, we can remove the <code class="codecolorer text solarized-light"><span class="text">StandardOutPath</span></code> and <code class="codecolorer text solarized-light"><span class="text">StandardErrorPath</span></code> keys (they default to the system log) and define our own environment variables in the job by setting the <code class="codecolorer text solarized-light"><span class="text">EnvironmentVariables</span></code> key like so:</p>
<div class="codecolorer-container xml solarized-light" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>EnvironmentVariables<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>JPI_PLUGIN2_DEBUG<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>&nbsp; &nbsp; &nbsp; <br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></div>
<p>Of course, as soon as you modify this LaunchAgent to help you debug this, the Helper-Tool job helpfully runs and resets your modified <code class="codecolorer text solarized-light"><span class="text">StartCalendarInterval</span></code> values and mangles your debug flag, because it just so happens to be looking for the string &#8220;2&#8243; <em>anywhere</em> in the plist and sets it to a random day-of-week integer. When I was originally debugging this, I commented out enough of the Helper-Tool script to prevent it from resetting my changes to the plist. I&#8217;d then unload and load the LaunchDaemon.</p>
<h3>Diagnostic self-obfuscation</h3>
<p>While Oracle&#8217;s JRE package was clearly not meant to be consumed and scrutized in this manner by any user (or sane person), one has to seriously wonder why someone thought it helpful to go to such lengths to obfuscate the system&#8217;s own mechanisms, hiding all traces of useful logging and status info; compare to the verbose output of Google&#8217;s Keystone daemon during a background Chrome update. Setting aside the bizarre self-healing schedule – for something that probably <em>should</em> be nagging the user once a day to update, since Apple will block it the next anyway – it&#8217;s amazing how difficult the package even makes it to test and debug its behavior. It seems that the release engineer on this project was not interested in being able to debug and test this easily himself.</p>
]]></content:encoded>
			<wfw:commentRss>http://macops.ca/java-7-how-not-to-use-launchd-for-your-app/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Managing Xcode CLI tools</title>
		<link>http://macops.ca/managing-xcode-cli-tools/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=managing-xcode-cli-tools</link>
		<comments>http://macops.ca/managing-xcode-cli-tools/#comments</comments>
		<pubDate>Fri, 15 Mar 2013 14:54:43 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[munki]]></category>
		<category><![CDATA[vendor metadata]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://macops.ca/?p=453</guid>
		<description><![CDATA[In a previous post on deploying Xcode components, I showed how the iOS Simulators are defined in a metadata file used by Apple, called dvtdownloadableindex, which is a binary plist containing information about all the &#8220;Components&#8221; available in the Downloads preference area. What&#8217;s useful about this file is that it describes in a human-readable way [...]]]></description>
				<content:encoded><![CDATA[<p>In a previous post on <a href="http://macops.ca/xcode-deployment-the-dvtdownloadableindex-and-ios-simulators/" title="Xcode deployment: The dvtdownloadableindex and iOS Simulators/SDKs">deploying Xcode components</a>, I showed how the iOS Simulators are defined in a metadata file used by Apple, called <code class="codecolorer text solarized-light"><span class="text">dvtdownloadableindex</span></code>, which is a binary plist containing information about all the &#8220;Components&#8221; available in the Downloads preference area.</p>
<p>What&#8217;s useful about this file is that it describes in a human-readable way what Xcode uses to determine what component updates are available and what&#8217;s already installed. Up until yesterday, the CLI tools used only SHA-1 sums on specific binaries and libraries to determine whether the package was installed, which was somewhat frustrating to those of us deploying it, because it meant the actual package receipt version numbers were next to useless. Munki, for example, couldn&#8217;t use these to determine installed status, but one could at least use these to know what files to use to track the installation. Munki can use MD5 checksums to specify a file&#8217;s contents.</p>
<p>Here&#8217;s how they used to check their installed state:</p>
<div class="codecolorer-container xml solarized-light" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>InstalledIfAllSHA1SumsMatch<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>/usr/bin/clang<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>d8d5e4dcd2026aaeb5f98c691849fcde288b02db<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>/usr/bin/lldb<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>58a667d1bdeca37b46eebb7f307e6dc9ccc2a105<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>/usr/lib/libSystem.B_debug.dylib<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>451b59324546917f98b7b3a7e952408dfe4a6510<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></div>
<p>And here&#8217;s the full entry for the latest version (4.5.9) of the CLI tools for Mountain Lion, released yesterday on March 14, 2013:</p>
<div class="codecolorer-container xml solarized-light" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:400px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dependencies<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;array</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>fileSize<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;integer<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>118401880<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/integer<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>identifier<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Xcode.CLTools.10.8<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>name<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Command Line Tools<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>source<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>http://devimages.apple.com/downloads/xcode/command_line_tools_for_xcode_os_x_mountain_lion_march_2013.dmg<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>userInfo<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>ActivationPredicate<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>$MAC_OS_X_VERSION &gt;= '10.8.0' <span style="color: #ddbb00;">&amp;&amp; $MAC_OS_X_VERSION &lt; '10.9.0'&lt;/string&gt;</span><br />
<span style="color: #ddbb00;"> &nbsp; &nbsp; &nbsp; &nbsp;&lt;key&gt;InstallPrefix&lt;/key&gt;</span><br />
<span style="color: #ddbb00;"> &nbsp; &nbsp; &nbsp; &nbsp;&lt;string&gt;/&lt;/string&gt;</span><br />
<span style="color: #ddbb00;"> &nbsp; &nbsp; &nbsp; &nbsp;&lt;key&gt;InstalledIfAllReceiptsArePresentOrNewer&lt;/key&gt;</span><br />
<span style="color: #ddbb00;"> &nbsp; &nbsp; &nbsp; &nbsp;&lt;dict&gt;</span><br />
<span style="color: #ddbb00;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;key&gt;com.apple.pkg.DevSDK&lt;/key&gt;</span><br />
<span style="color: #ddbb00;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;string&gt;10.8.0.0.1.1306847324&lt;/string&gt;</span><br />
<span style="color: #ddbb00;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;key&gt;com.apple.pkg.DeveloperToolsCLI&lt;/key&gt;</span><br />
<span style="color: #ddbb00;"> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;string&gt;4.6.0.0.1.1362189000&lt;/string&gt;</span><br />
<span style="color: #ddbb00;"> &nbsp; &nbsp; &nbsp; &nbsp;&lt;/dict&gt;</span><br />
<span style="color: #ddbb00;"> &nbsp; &nbsp; &nbsp; &nbsp;&lt;key&gt;RequiresADCAuthentication&lt;/key&gt;</span><br />
<span style="color: #ddbb00;"> &nbsp; &nbsp; &nbsp; &nbsp;&lt;false/&gt;</span><br />
<span style="color: #ddbb00;"> &nbsp; &nbsp; &nbsp; &nbsp;&lt;key&gt;Summary&lt;/key&gt;</span><br />
<span style="color: #ddbb00;"> &nbsp; &nbsp; &nbsp; &nbsp;&lt;string&gt;Before installing, note that from within Terminal you can use the XCRUN tool to launch compilers and other tools embedded within the Xcode application. Use the XCODE-SELECT tool to define which version of Xcode is active. &nbsp;Type &quot;man xcrun&quot; from within Terminal to find out more.</span><br />
<br />
<span style="color: #ddbb00;"> &nbsp; &nbsp; &nbsp; &nbsp;Downloading this package will install copies of the core command line tools and system headers into system folders, including the LLVM compiler, linker, and build tools.&lt;/string&gt;</span><br />
<span style="color: #ddbb00;"> &nbsp; &nbsp; &nbsp; &nbsp;&lt;key&gt;Xcode.SDKs&lt;/key&gt;</span><br />
<span style="color: #ddbb00;"> &nbsp; &nbsp; &nbsp; &nbsp;&lt;array/&gt;</span><br />
<span style="color: #ddbb00;"> &nbsp; &nbsp;&lt;/dict&gt;</span><br />
<span style="color: #ddbb00;"> &nbsp; &nbsp;&lt;key&gt;version&lt;/key&gt;</span><br />
<span style="color: #ddbb00;"> &nbsp; &nbsp;&lt;string&gt;4.5.9&lt;/string&gt;</span><br />
<span style="color: #ddbb00;">&lt;/dict&gt;</span></div></div>
<p>Notice we have a download path, it doesn&#8217;t require authentication to the Apple Developer Center (not long ago they did), and note in particular the <code class="codecolorer text solarized-light"><span class="text">InstalledIfAllReceiptsArePresentOrNewer</span></code> key, with a dictionary of package receipts and versions. If I generate a new Munki pkginfo for this installer, my receipts array looks like this:</p>
<div class="codecolorer-container xml solarized-light" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>receipts<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;array<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>installed_size<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;integer<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>238426<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/integer<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>packageid<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>com.apple.pkg.DevSDK<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>version<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>10.8.0.0.1.1306847324<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>installed_size<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;integer<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>253950<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/integer<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>packageid<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>com.apple.pkg.DeveloperToolsCLI<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>version<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>4.6.0.0.1.1362189000<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/array<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></div>
<p>&#8230;which is much nicer than managing a bunch of file checksums. Hopefully they start using only receipts from now on.</p>
]]></content:encoded>
			<wfw:commentRss>http://macops.ca/managing-xcode-cli-tools/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Everything you&#8217;ll wish you didn&#8217;t know about disabling Java 7 updates</title>
		<link>http://macops.ca/everything-youll-wish-you-didnt-know-about-disabling-java-7-updates/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=everything-youll-wish-you-didnt-know-about-disabling-java-7-updates</link>
		<comments>http://macops.ca/everything-youll-wish-you-didnt-know-about-disabling-java-7-updates/#comments</comments>
		<pubDate>Mon, 25 Feb 2013 01:11:38 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[Disabling update checks]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[launchd]]></category>
		<category><![CDATA[Sparkle]]></category>

		<guid isPermaLink="false">http://macops.ca/?p=406</guid>
		<description><![CDATA[Oracle&#8217;s Java 7 JRE for OS X was first officially released in October 2012. As expected, there have been issues deploying and testing it, amidst confusion about Apple&#8217;s Java 6 updates and it disabling symlinks to the web plugin, the pre-emptive disabling of Java with XProtect, and more. And of course, the first thing administrators [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://macops.ca/wp-content/uploads/2013/02/JavaCupLogo-161.png"><img src="http://macops.ca/wp-content/uploads/2013/02/JavaCupLogo-161.png" alt="JavaCupLogo-161" width="81" height="162" class="alignleft size-full wp-image-384" /></a>Oracle&#8217;s Java 7 JRE for OS X was first officially released in October 2012. As expected, there have been issues deploying and testing it, amidst confusion about Apple&#8217;s Java 6 updates and it disabling symlinks to the web plugin, the pre-emptive disabling of Java with XProtect, and more.</p>
<p>And of course, the first thing administrators need to verify is that deployed software won&#8217;t periodically nag the user to install an update that they don&#8217;t have sufficient rights to install, or that they shouldn&#8217;t install for other reasons. I&#8217;ll cover a few ideas in this post specifically about the updater mechanisms and approaches to disabling it, and focus on other specific issues with this package in future posts.</p>
<p><span id="more-406"></span></p>
<h3>deployment.properties a.k.a. com.oracle.javadeployment a.k.a. com.oracle.java.JavaAppletPlugin a.k.a. com.oracle.java.Java-Updater a.k.a. com.oracle.java.Helper-Tool</h3>
<p>There is a place to disable update checks in the Java Control Panel:</p>
<div id="attachment_427" class="wp-caption alignnone" style="width: 624px"><a href="http://macops.ca/wp-content/uploads/2013/02/javacontrolpanel-updates.png"><img src="http://macops.ca/wp-content/uploads/2013/02/javacontrolpanel-updates.png" alt="Look! It unchecked the checkbox!" width="614" height="613" class="size-full wp-image-427" /></a><p class="wp-caption-text">Look! It unchecked the checkbox!</p></div>
<p>Java uses what&#8217;s known as a &#8220;Java properties&#8221; format to store preferences, that looks similar to a .ini file. Many user preferences seem to touch a file at <code class="codecolorer text solarized-light"><span class="text">/Library/Application Support/Oracle/Java/Deployment/deployment.properties</span></code>. This file&#8217;s options are somewhat <a href="http://docs.oracle.com/javase/7/docs/technotes/guides/deployment/deployment-guide/properties.html">documented</a>.</p>
<p>In more recent versions, some settings (perhaps those known to have OS X-specific implementations, like the boolean <code class="codecolorer text solarized-light"><span class="text">deployment.macosx.check.update</span></code>) seem to be stored instead in the defaults domain <code class="codecolorer text solarized-light"><span class="text">com.oracle.javadeployment</span></code> in a Java-style namespace:</p>
<pre>

<div class="codecolorer-container xml solarized-light" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>/com/oracle/javadeployment/<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>deployment.macosx.check.update<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>false<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>deployment.modified.timestamp<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>1361734949180<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>deployment.version<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>7.0<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></div>

</pre>
<p>It doesn&#8217;t actually matter for now where the <code class="codecolorer text solarized-light"><span class="text">deployment.macosx.check.update</span></code> setting is actually stored, because it has no effect on whether or not Java 7 will check for updates.</p>
<p><strong>Update 13/03/15:</strong> It <a href="http://macops.ca/everything-youll-wish-you-didnt-know-about-disabling-java-7-updates/#comment-53">turns out</a> that this does have an effect, it controls the plugin&#8217;s own built-in update checker, that I managed to never see while scrutinizing the Sparkle-based updater. So while it suppresses the nag when the plugin is actually invoked, it doesn&#8217;t control the background update check mechanism that&#8217;s detailed below and in a <a href="http://macops.ca/java-7-how-not-to-use-launchd-for-your-app/" title="Java 7: How not to use launchd for your app">related post</a>.</p>
<div id="attachment_437" class="wp-caption alignnone" style="width: 710px"><a href="http://macops.ca/wp-content/uploads/2013/02/java7_sparkle.png"><img src="http://macops.ca/wp-content/uploads/2013/02/java7_sparkle.png" alt="What? Oh." width="700" height="506" class="size-full wp-image-437" /></a><p class="wp-caption-text">What? Oh.</p></div>
<p>There&#8217;ve been a <a href="https://groups.google.com/d/topic/munki-dev/aDapiQcwu3o/discussion">few</a> <a href="https://jamfnation.jamfsoftware.com/discussion.html?id=6489">discussion</a> <a href="https://jamfnation.jamfsoftware.com/discussion.html?id=6639">threads</a> about configuring the update setting, but all these attempts seem to do is tell the Control Panel about the state of the checkbox, and not suppress the active checking (and prompting) for updates.</p>
<h3>The Java-Updater/Helper-Tool Yin-Yang of Doom</h3>
<p>Briefly, here are the basic mechanisms of the update-checking system as it is now (here&#8217;s the <a href="https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man5/launchd.plist.5.html">launchd manpage</a> for reference):</p>
<ul>
<li>There is a LaunchDaemon (<code class="codecolorer text solarized-light"><span class="text">com.oracle.java.Helper-Tool.plist</span></code>) and a LaunchAgent (<code class="codecolorer text solarized-light"><span class="text">com.oracle.java.Java-Updater.plist</span></code>) installed in the usual place within <code class="codecolorer text solarized-light"><span class="text">/Library</span></code>.</li>
<li>They are actually symlinks to the web plugin&#8217;s installation area, in <code class="codecolorer text solarized-light"><span class="text">/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Resources</span></code>.</li>
<li>The LaunchDaemon is not run on a schedule, but rather triggered by changes to the LaunchAgent plist file using a <code class="codecolorer text solarized-light"><span class="text">WatchPaths</span></code> entry.</li>
<li>The LaunchDaemon runs <code class="codecolorer text solarized-light"><span class="text">Helper-Tool</span></code>, a Bash script whose purpose is to enforce (based on default times set by an install script) or randomize the <code class="codecolorer text solarized-light"><span class="text">StartCalendarInterval</span></code> key in the LaunchAgent plist, and reload the LaunchAgent. It modifies the file that triggers itself to run&#8230; to modify the file&#8230; that triggers it to run&#8230; you can probably see why this may not be a great idea.</li>
<li>The LaunchAgent runs the <code class="codecolorer text solarized-light"><span class="text">Java Updater</span></code> binary located inside a .app bundle in the aforementioned <code class="codecolorer text solarized-light"><span class="text">Resources</span></code> directory.</li>
<li>Java Updater.app is essentially a vessel for the <a href="http://sparkle.andymatuschak.org/">Sparkle updater framework</a>, which simply manually calls Sparkle&#8217;s &#8220;check in background&#8221; function. It is a pure Cocoa app. It does not seem to have any link to the Java plugin, settings configurable via the control panel, etc. It is not linked to any Java library.</li>
</ul>
<p>There are a several major issues with this LaunchAgent/Daemon combo that I&#8217;ll cover in a future post.</p>
<p>For now, there are a couple possible workarounds I&#8217;d consider that are the least intrusive and most reliable way of suppressing the update check behavior. They each still have issues that are very important to understand if you want to deploy this and not dig yourself out of a hole later. I don&#8217;t consider either of them acceptable in the long term, and can&#8217;t recommend one over the other &#8211; it all depends on your environment.</p>
<h3>Neuter Sparkle</h3>
<p>One approach is to leverage the configurability of Sparkle. Because Java Updater is directly invoking Sparkle&#8217;s check method, overriding check behavior preference keys as outlined <a href="https://github.com/andymatuschak/Sparkle/wiki/customization">here</a> won&#8217;t help, as far as I can tell. If you can at least read some Objective-C code you can look at Sparkle&#8217;s <a href="https://github.com/andymatuschak/Sparkle/blob/master/SUUpdater.m">SUUpdater.m</a> and see for yourself what it does, and make a pretty good guess at what methods Java Updater is calling by inspecting its binary strings (hint: the <code class="codecolorer text solarized-light"><span class="text">resetUpdateCycle</span></code> and <code class="codecolorer text solarized-light"><span class="text">checkForUpdatesInBackground</span></code> methods).</p>
<p>Sparkle supports overriding some preference keys that would typically be defined in a bundle&#8217;s <code class="codecolorer text solarized-light"><span class="text">Info.plist</span></code> file, by setting them in the bundle&#8217;s user defaults domain instead (at either the user or system level). In this case, we&#8217;re looking at the <code class="codecolorer text solarized-light"><span class="text">com.oracle.java.JavaAppletPlugin</span></code> domain, and the <code class="codecolorer text solarized-light"><span class="text">SUFeedURL</span></code> string key. (It might be worth pointing out now that the Java 7 package uses about 4 different preference domains for the plugin and helpers, which doesn&#8217;t make figuring these out any easier).</p>
<p>Setting <code class="codecolorer text solarized-light"><span class="text">SUFeedURL</span></code> to an invalid URL like &#8220;nil&#8221; (or one that doesn&#8217;t actually contain a Sparkle appcast feed) will cause Sparkle to <a href="https://github.com/andymatuschak/Sparkle/blob/master/SUUpdater.m#L334">fail silently</a>. It&#8217;s worth noting, since this is being run as a LaunchAgent, that this doesn&#8217;t cause the actual Java Updater app to fail with a non-zero exit code. As far as Java Updater is concerned, it&#8217;s done its job and Sparkle just didn&#8217;t have anything for it to do.</p>
<p>There are alternate, more desperate Sparkle-related tweaks possible that will yield similar results to the above, which will be in a future post.</p>
<p><strong>Advantages:</strong> This preference key can be managed like any other: a <code class="codecolorer text solarized-light"><span class="text">defaults</span></code> command writing the value to <code class="codecolorer text solarized-light"><span class="text">/Library/Preferences/com.oracle.java.JavaAppletPlugin</span></code>, MCX, or a Configuration Profile. The preference can later be removed/changed if desired, and it&#8217;s completely independent of the plugin installation.</p>
<p><strong>Disadvantages:</strong> This overrides the update URL for anywhere the plugin may want to check for updates, meaning that if one checks the Control Panel manually for an update, it will not be able to check or verify whether it is up to date. It will state that it was last run whenever Java Updater was last run, but that it is &#8220;Unable to check for updates&#8221;, and to &#8220;Please check your internet connection and try again.&#8221; You&#8217;re essentially removing the ability for the plugin to update itself via its built-in mechanisms, even the user- or support-initiated ones. This puts it roughly on par with the <a href="http://managingosx.wordpress.com/2012/08/22/flash-mob/">state</a> of <a href="http://managingosx.wordpress.com/2012/08/19/more-on-flash-player-11-3/">deploying</a> <a href="http://managingosx.wordpress.com/2012/08/24/flash-dance">Adobe Flash</a>.</p>
<h3>Remove (but don&#8217;t disable) the LaunchAgent</h3>
<p>A second approach is to prevent the LaunchAgent from ever running Java Updater in the first place.</p>
<p>After installing Java, unload the job temporarily, and remove the symlinks so that it&#8217;s not loaded again after a restart. You&#8217;d run something like this with elevated privileges:</p>
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">/bin/launchctl unload /Library/LaunchAgents/com.oracle.java.Java-Updater.plist<br />
/bin/launchctl unload /Library/LaunchDaemons/com.oracle.java.Java-Helper.plist<br />
/bin/rm -f /Library/LaunchAgents/com.oracle.java.Java-Updater.plist<br />
/bin/rm -f /Library/LaunchDaemons/com.oracle.java.Java-Helper.plist</div></div>
<p>You might think, like I <a href="https://groups.google.com/d/msg/macenterprise/Vjoe-qo1ttA/Gkk4NyS2nfYJ">did</a>, that you can just <code class="codecolorer text solarized-light"><span class="text">launchctl unload -w</span></code> the job to set it as permanently disabled. It <a href="https://groups.google.com/d/msg/macenterprise/Vjoe-qo1ttA/5dzpAUemVkEJ">turns out</a> you <strong>absolutely should not do</strong> this, due to an oversight in the Java 7 installer&#8217;s postinstall script. Having these jobs disabled will cause the script, and thus the entire install, to fail.</p>
<p><strong>Advantages:</strong> We don&#8217;t need to mess with any configuration of the updater mechanism itself.</p>
<p><strong>Disadvantages:</strong> We&#8217;re still changing the &#8220;expected state&#8221; of the Java installation, and the fact that disabling the job permanently (ie. <code class="codecolorer text solarized-light"><span class="text">launchctl unload -w</span></code>) causes future installations to fail doesn&#8217;t inspire confidence that any of Oracle&#8217;s future pre/postinstall scripts will be robust enough or perform even basic sanity checks. We also need to make sure that we unload the job and remove symlinks after every installation. Unloading is actually optional, since that the next update check will usually be a week from the time of installation, and a reboot will cause the launchd jobs to never be loaded again.</p>
<h3>Current status</h3>
<p>I don&#8217;t think either option is generally viable, especially if you&#8217;re in environment with a diverse set of client configurations (laptops, admin users, remote workers and sites, etc.) and need to make as few assumptions as possible about how client machines are used and maintained. If, on the other hand, you maintain control over at least software installations and updates, you might decide one of these two workarounds could work despite its limitations, at least until a better solution is discovered or implemented.</p>
<p>After I complained in <a href="http://webchat.freenode.net/?channels=#%23osx-server">##osx-server</a> on IRC, Michael Lynn <a href="http://osx.michaellynn.org/freenode-osx-server/freenode-osx-server_2013-02-23.html">found</a> a channel through which to report bugs against the JRE, and Rich Trouton documented the steps and caveats in a <a href="http://derflounder.wordpress.com/2013/02/23/filing-bugreports-with-oracle-for-mac-os-xs-java-7">blog post</a>. If you support Java on your Macs and this is an issue for you, file a bug!</p>
]]></content:encoded>
			<wfw:commentRss>http://macops.ca/everything-youll-wish-you-didnt-know-about-disabling-java-7-updates/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>New utility: XProtect Packager</title>
		<link>http://macops.ca/new-utility-xprotect-packager/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=new-utility-xprotect-packager</link>
		<comments>http://macops.ca/new-utility-xprotect-packager/#comments</comments>
		<pubDate>Mon, 11 Feb 2013 17:13:58 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[munki]]></category>
		<category><![CDATA[packaging]]></category>
		<category><![CDATA[vendor metadata]]></category>
		<category><![CDATA[xprotect]]></category>

		<guid isPermaLink="false">http://macops.ca/?p=368</guid>
		<description><![CDATA[Roughly a week after the first widespread panic with the XProtect mechanism disabling Java on OS X, the same thing happened with the Flash plugin, with Apple issuing a definition update blocking all old versions about 3 hours after the latest Flash was available. (At least this time a newer version was available.) It&#8217;s clear [...]]]></description>
				<content:encoded><![CDATA[<p>Roughly a week after the first widespread panic with the XProtect mechanism disabling Java on OS X, the same thing happened with the Flash plugin, with Apple issuing a definition update blocking all old versions about 3 hours after the latest Flash was available. (At least this time a newer version <em>was</em> available.)</p>
<p>It&#8217;s clear that a management strategy could be very useful in environments where users aren&#8217;t admins on their computers and can&#8217;t install updates themselves. One such strategy is to simply disable the updater, but the definitions should still be pushed to clients as you roll out new plugin versions, to enforce minimum security requirements as well as be able to protect against known malware.</p>
<p>There was some talk on Twitter, IRC and <a href="http://managingosx.wordpress.com/2013/02/01/more-thoughts-on-xprotect-updater">multiple</a> <a href="http://managingosx.wordpress.com/2013/02/04/still-more-on-the-xprotect-updater">posts</a> on Greg Neagle&#8217;s blog. I dug around the <code class="codecolorer text solarized-light"><span class="text">XprotectUpdater</span></code> binary and posted some <a href="http://macops.ca/monitoring-apples-xprotect-meta-feed-for-changes/" title="Monitoring Apple’s XProtect meta feed for changes">ideas</a> on how one could monitor this feed for changes.</p>
<p>I later realized that there are also multiple definition files: one for each major version of OS X, starting with Snow Leopard, when XProtect was first implemented. This means there will soon be four separate defintions to keep track of (at least until Apple stops providing security updates for Snow Leopard).</p>
<p>I wrote a basic utility to automate packaging up these changes as the definition file (&#8216;clientConfiguration.plist&#8217;) is updated from Apple. Because what <code class="codecolorer text solarized-light"><span class="text">XprotectUpdater</span></code> does to synthesize the two Xprotect definition files on the client is very simple, this tool can do the same thing, but for all available client versions. Meaning, you can run the command on a single machine (and on a schedule, if you wish) and automatically build new packages for all OS X client versions you support.</p>
<p>It&#8217;s called XProtect Packager, available here:</p>
<p><a href="https://github.com/timsutton/XProtectPackager">https://github.com/timsutton/XProtectPackager</a></p>
<p>It&#8217;s also able to automatically push these updated packages to a Munki repository.</p>
<p>On the subject of Munki, there are a few different &#8220;auto-packager&#8221; tools that have been made available by different people. Because I wanted this tool to be self-contained and finished as quickly as possible, the mechanisms for building the package and importing into Munki are quite basic, and the tool&#8217;s functionality would probably be better served by integrating into a tool like Per Olofsson&#8217;s <a href="http://code.google.com/p/macautopkg">AutoPkg</a> or <a href="http://neographophobic.github.com/autoMunkiImporter">another</a> <a href="https://github.com/jamesez/automunki">recipe-based</a> checking/building/importing tool for Munki integration. If one tool starts to see some more widespread adoption and community contribution, it would be great to integrate XProtect Packager&#8217;s functionality into it.</p>
]]></content:encoded>
			<wfw:commentRss>http://macops.ca/new-utility-xprotect-packager/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Monitoring Apple&#8217;s XProtect meta feed for changes</title>
		<link>http://macops.ca/monitoring-apples-xprotect-meta-feed-for-changes/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=monitoring-apples-xprotect-meta-feed-for-changes</link>
		<comments>http://macops.ca/monitoring-apples-xprotect-meta-feed-for-changes/#comments</comments>
		<pubDate>Sat, 02 Feb 2013 20:22:30 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[plugin blacklist]]></category>
		<category><![CDATA[vendor metadata]]></category>
		<category><![CDATA[xprotect]]></category>

		<guid isPermaLink="false">http://macops.ca/?p=342</guid>
		<description><![CDATA[Greg had an interesting blog post yesterday on handling Apple&#8217;s XProtect Updater mechanism for managed environments, as admins were still scrambling to resolve clients that suddenly had their Java Web Plugin disabled and no newer version available to install that would satisfy Apple&#8217;s minimum version requirements defined in its XProtect blacklist (new versions of Java [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://macops.ca/wp-content/uploads/2013/02/java-webstart_256.png"><img src="http://macops.ca/wp-content/uploads/2013/02/java-webstart_256.png" alt="java-webstart_256.png" width="256" height="256" class="alignleft size-full wp-image-356" /></a>Greg had an <a href="http://managingosx.wordpress.com/2013/02/01/more-thoughts-on-xprotect-updater/">interesting blog post</a> yesterday on handling Apple&#8217;s XProtect Updater mechanism for managed environments, as admins were still scrambling to resolve clients that suddenly had their Java Web Plugin disabled and no newer version available to install that would satisfy Apple&#8217;s minimum version requirements defined in its XProtect blacklist (new versions of <a href="http://support.apple.com/kb/DL1573">Java 6 from Apple</a> for OS X 10.6 and <a href="http://www.oracle.com/technetwork/java/javase/downloads/jre7-downloads-1880261.html">Java 7 from Oracle</a> have since been posted).</p>
<p>Maybe you&#8217;d like to at the very least know when this has been updated, and what are the nature of the changes. Here&#8217;s another example where the <code class="codecolorer text solarized-light"><span class="text">strings</span></code> command proves useful, and it&#8217;s quickly obvious what&#8217;s going on.</p>
<p>If we look in <code class="codecolorer text solarized-light"><span class="text">/System/Library/LaunchDaemons</span></code> for something related to XProtect, we find <code class="codecolorer text solarized-light"><span class="text">com.apple.xprotectupdater.plist</span></code>. Opening it, we see it simply runs the executable at <code class="codecolorer text solarized-light"><span class="text">/usr/libexec/XProtectUpdater</span></code> every 86400 seconds (or 24 hours).</p>
<p>Now, run the <code class="codecolorer text solarized-light"><span class="text">strings</span></code> command on this binary, and see a few telltale methods and values (this is taken from somewhere in the middle):</p>
<div class="codecolorer-container text solarized-light" style="border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">http://configuration.apple.com/configurations/macosx/xprotect/2/clientConfiguration.plist<br />
/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/XProtect.meta.plist<br />
Version<br />
LastModification<br />
FetchURL<br />
StartInterval<br />
VPROC_GSK_START_INTERVAL change failed: %lu<br />
SCNetworkReachabilityCreateWithName failed: %s<br />
SCNetworkReachabilitySetCallback failed: %s<br />
SCNetworkReachabilityScheduleWithRunLoop failed: %s<br />
If-Modified-Since<br />
NSURLConnection error: %@<br />
Unexpected status code: %ld<br />
Unable to verify signature: %@<br />
meta<br />
Ignoring new signature plist: Not an increase in version<br />
Last-Modified<br />
EEE',' dd MMM yyyy HH':'mm':'ss 'GMT'<br />
Last-modified date is later in time than current date</div></div>
<p>Taking note of the URL at the top, we can simply <code class="codecolorer text solarized-light"><span class="text">curl</span></code> this URL to see that it&#8217;s nothing more than a plaintext XML plist prepended with a security signature (the same signature that&#8217;s getting written to <code class="codecolorer text solarized-light"><span class="text">XProtect.meta.plist</span></code>. Looking at the other strings, it&#8217;s clear that it&#8217;s using the Last-Modified HTTP header to compare this date with the current system date (&#8220;Last-modified date is later in time than current date&#8221;). It&#8217;s also using the <code class="codecolorer text solarized-light"><span class="text">Version</span></code> key in the plist to determine whether the plist available from Apple is more recent than the one already installed.</p>
<p>Note, the &#8220;2&#8243; in the URL <code class="codecolorer text solarized-light"><span class="text">..xprotect/2/clientConfiguration.plist</span></code> is what was returned on my Lion machine. Snow Leopard clients look for &#8220;1&#8243;, Mountain Lion clients look for &#8220;3&#8243;, and so on.</p>
<p>Now we can throw this plist URL into a site like <a href="https://www.changedetection.com/">ChangeDetection.com</a>, and ask it to check this URL once per day and send us an e-mail if it&#8217;s changed. We can see the details on the change, and when it was last modified. <strong>Update:</strong> Given that Apple&#8217;s updated this list within hours of new Flash/Java releases and will probably continue to do so, checking daily is probably not frequent enough.</p>
<p>We could also use an application like <a href="http://jenkins-ci.org">Jenkins</a>,  that already handles polling, jobs, and notifications. The <a href="https://wiki.jenkins-ci.org/display/JENKINS/URLTrigger+Plugin">URLTrigger</a> works well for this, and we can simply ask it to track the last modified date of the URL however frequently we&#8217;d like, up to the minute if we so wish. From this point on we could write the <code class="codecolorer text solarized-light"><span class="text">XProtect.meta.plist</span></code> file ourselves, package it and automatically push it to test clients, or anything we could dream up.</p>
<p>If we want to extract more information, we can also write a very simple script to do so, put it into a versioning system along with the <code class="codecolorer text solarized-light"><span class="text">PluginBlacklist</span></code> information, etc. This example just prints out the version of the meta plist:</p>
<div class="codecolorer-container bash solarized-light" style="border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #007800;">URL</span>=http:<span style="color: #000000; font-weight: bold;">//</span>configuration.apple.com<span style="color: #000000; font-weight: bold;">/</span>configurations<span style="color: #000000; font-weight: bold;">/</span>macosx<span style="color: #000000; font-weight: bold;">/</span>xprotect<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">2</span><span style="color: #000000; font-weight: bold;">/</span>clientConfiguration.plist<br />
curl <span style="color: #660033;">-s</span> <span style="color: #007800;">$URL</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'/\&lt;\?xml/{i++}i'</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000; font-weight: bold;">/</span>tmp<span style="color: #000000; font-weight: bold;">/</span>meta.plist<br />
<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>libexec<span style="color: #000000; font-weight: bold;">/</span>PlistBuddy <span style="color: #660033;">-c</span> <span style="color: #ff0000;">'Print :meta:Version'</span> <span style="color: #000000; font-weight: bold;">/</span>tmp<span style="color: #000000; font-weight: bold;">/</span>meta.plist</div></div>
<p>Lots of ways to solve a trivial problem! I&#8217;m not advocating whether or not to take measures to disable the XProtect mechanism on all your managed clients, but this might at least give some ideas on how you can at least be kept up to date with Apple&#8217;s new minimum security requirements for plugins, known malware, and anything  else Apple will add to XProtect in the future.</p>
]]></content:encoded>
			<wfw:commentRss>http://macops.ca/monitoring-apples-xprotect-meta-feed-for-changes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introducing Brigadier, a tool for automated Boot Camp driver download and installation</title>
		<link>http://macops.ca/introducing-brigadier-a-tool-for-automated-boot-camp-driver-download-and-installation/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=introducing-brigadier-a-tool-for-automated-boot-camp-driver-download-and-installation</link>
		<comments>http://macops.ca/introducing-brigadier-a-tool-for-automated-boot-camp-driver-download-and-installation/#comments</comments>
		<pubDate>Tue, 29 Jan 2013 20:15:10 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Boot Camp]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://macops.ca/?p=330</guid>
		<description><![CDATA[Anyone doing Windows deployment on Macs, and dealing with getting and installing the Boot Camp drivers, has probably found it to be a pain point. I recently wrote a small tool called Brigadier that I&#8217;m now testing in my environment, that will fetch Boot Camp ESD packages for any model from either OS X or [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://macops.ca/introducing-brigadier-a-tool-for-automated-boot-camp-driver-download-and-installation/bootcamp_drives_128-png/" rel="attachment wp-att-332"><img src="http://macops.ca/wp-content/uploads/2013/01/bootcamp_drives_128.png" alt="bootcamp_drives_128.png" width="128" height="128" class="alignleft size-full wp-image-332" /></a>Anyone doing Windows deployment on Macs, and dealing with getting and installing the Boot Camp drivers, has probably found it to be a pain point. I recently wrote a small tool called Brigadier that I&#8217;m now testing in my environment, that will fetch Boot Camp ESD packages for any model from either OS X or Windows.. and even install them automatically on Windows. You can point it to your internal SUS for fast download speeds.</p>
<p>It&#8217;s written in Python, but if you want to run it on Windows, there&#8217;s a single-file executable available as well, so that Python isn&#8217;t required to be installed.</p>
<p>This might be interesting to you if you are doing an automated install of the drivers as a post-imaging task for deploying Windows images, because it handles downloading the correct package for the hardware running it. It&#8217;s also a convenient way to get the right install package for a particular model (if, for example, you support other technicians setting up Boot Camp, but for whatever reason they&#8217;re having problems getting the drivers.)</p>
<p>It can be downloaded from its GitHub repo <a href="https://github.com/timsutton/brigadier">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://macops.ca/introducing-brigadier-a-tool-for-automated-boot-camp-driver-download-and-installation/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Rolling OS X packages with FPM and Homebrew</title>
		<link>http://macops.ca/rolling-os-x-packages-with-fpm-and-homebrew/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=rolling-os-x-packages-with-fpm-and-homebrew</link>
		<comments>http://macops.ca/rolling-os-x-packages-with-fpm-and-homebrew/#comments</comments>
		<pubDate>Sat, 19 Jan 2013 20:15:54 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[fpm]]></category>
		<category><![CDATA[homebrew]]></category>
		<category><![CDATA[packaging]]></category>

		<guid isPermaLink="false">http://macops.ca/?p=299</guid>
		<description><![CDATA[Two cool open-source package managers, FPM and Homebrew, recently got some new OS X Installer Package capabilities. fpm -t osxpkg Jordan Sissel&#8217;s FPM packaging tool was designed for systems administrators to very easily roll packages for RedHat, Debian and other platforms and abstract away the obscure details of the package formats themselves. FPM is written [...]]]></description>
				<content:encoded><![CDATA[<p>Two cool open-source package managers, FPM and Homebrew, recently got some new OS X Installer Package capabilities.</p>
<h2>fpm -t osxpkg</h2>
<p>Jordan Sissel&#8217;s <a href="https://github.com/jordansissel/fpm">FPM</a> packaging tool was designed for systems administrators to very easily roll packages for RedHat, Debian and other platforms and abstract away the obscure details of the package formats themselves.</p>
<p>FPM is written in Ruby, and I decided (somehow) it could be a fun learning exercise to look at implementing support in it for building OS X packages. FPM version 0.4.27 was released a few days ago, available as a <code class="codecolorer text solarized-light"><span class="text">gem install</span></code>, and now supports OS X package input and output, at least on OS X platforms with pkgbuild installed (built-in on OS X 10.8 and 10.7, for 10.6 requires an installation of Xcode 3.2.6 or later).</p>
<p>OS X packages are almost always used in a very different context than rpms and debs (and you are  hopefully never going to need to convert an rpm to an OS X package), but building them with FPM still allows one to benefit from some cool features FPM provides all with a single command invocation:</p>
<ul>
<li>automatically build packages from RubyGems, Python packages and others. <code class="codecolorer text solarized-light"><span class="text">fpm -s python -t osxpkg psutil</span></code> builds a pkg of the latest psutil Python module that will install to the build system&#8217;s default <code class="codecolorer text solarized-light"><span class="text">site-packages</span></code> folder. You can specify an alternate version to fetch with <code class="codecolorer text solarized-light"><span class="text">--version</span></code>.</li>
<li>pre/postinstall scripts can be ERB-templated with any properties of the package, ie. the version.</li>
<li>a package&#8217;s source can be a simple tarball, and you define the installation prefix.</li>
</ul>
<p>In addition to what we get with FPM for free, the <code class="codecolorer text solarized-light"><span class="text">osxpkg</span></code> package type in FPM also supports a few extras, the more noteworthy ones being: custom <a href="http://managingosx.wordpress.com/2012/07/05/stupid-tricks-with-pkgbuild/"><code class="codecolorer text solarized-light"><span class="text">restart-action</span></code></a> and <a href="http://macops.ca/flat-packages-persisting-obsolescence/" title="Flat packages: persisting obsolescence"><code class="codecolorer text solarized-light"><span class="text">dont-obsolete</span></code></a> values as simple command options rather than requiring manual PackageInfo templates. More options could easily be added as FPM already has built-in methods for templating package metadata files.</p>
<h2>brew pkg</h2>
<p>I was recently learning how to update a <a href="https://github.com/mxcl/homebrew/tree/master/Library/Formula/dfu-programmer.rb">Homebrew</a> package (ie. &#8216;formula&#8217;) so that I could compile an up-to-date version of <a href="http://dfu-programmer.sourceforge.net">dfu-programmer</a> on my Mac. I was reminded of several times at work when recent versions of packages I wanted to install were available in Homebrew, but didn&#8217;t want to just install Homebrew on a server, as it is targeted more towards developer systems and assumes ownership of /usr/local. I did like the idea that specific &#8216;formulae&#8217; are maintained voluntarily by people who probably know more than I about configuring/running a particular software on OS X, and that these are shareable and forkable if I wanted to improve one myself.</p>
<p>Homebrew provides a nice way to provide added functionality via custom scripts, and so was born <a href="https://github.com/timsutton/brew-pkg">brew-pkg</a>, a command to build an OS X installer package from an installed formula, with a couple bonuses:</p>
<ul>
<li>put service-related launchd plists in /Library/LaunchDaemons rather than a user folder</li>
<li>optionally include a package&#8217;s dependencies in the built package</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://macops.ca/rolling-os-x-packages-with-fpm-and-homebrew/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Flat packages: persisting obsolescence</title>
		<link>http://macops.ca/flat-packages-persisting-obsolescence/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=flat-packages-persisting-obsolescence</link>
		<comments>http://macops.ca/flat-packages-persisting-obsolescence/#comments</comments>
		<pubDate>Tue, 18 Dec 2012 00:22:20 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[packaging]]></category>
		<category><![CDATA[pkgbuild]]></category>

		<guid isPermaLink="false">http://macops.ca/?p=241</guid>
		<description><![CDATA[Packaging is somewhat of a black art on OS X. The Flat Package format has been in existence since 10.5, but only recently are more 3rd-party packaging tools like JAMF Composer starting to move to this format by default. PackageMaker&#8217;s days as a hidden download in the Apple Developer Center Auxiliary Downloads package are numbered. [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://macops.ca/flat-packages-persisting-obsolescence/pkg_256/" rel="attachment wp-att-249"><img src="http://macops.ca/wp-content/uploads/2012/12/pkg_256.png" alt="pkg_256" width="256" height="256" class="alignleft size-full wp-image-249" /></a></p>
<p>Packaging is somewhat of a black art on OS X. The Flat Package format has been in existence since 10.5, but only recently are more 3rd-party packaging tools like <a href="http://www.jamfsoftware.com/products/composer">JAMF Composer</a> starting to move to this format by default. PackageMaker&#8217;s days as a hidden download in the Apple Developer Center Auxiliary Downloads package are <a href="https://developer.apple.com/library/mac/#documentation/developertools/conceptual/PackageMakerUserGuide/RevisionHistory.html#//apple_ref/doc/uid/TP40005371-CH999-SW1">numbered</a>. In this post I&#8217;ll look at one aspect of the package system that&#8217;s perhaps less widely known, the &#8220;ownership&#8221; of a file to a package, and how this affects behaviour that can be tweaked when building flat packages, using <a href="https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man1/pkgbuild.1.html">pkgbuild</a> as the reference package-building tool.</p>
<p><span id="more-241"></span></p>
<p>By default, when an OS X package is installed, if it is an upgrade of a previous version (in other words, there is a package with the same <em>package identifier</em> of a lower version number already installed), any files in its payload that were present in the previous version and not in the new version will be removed from the filesystem. This is because these files are associated with that version of a package in the package (ie. &#8220;receipts&#8221;) database. When a new version of the package is installed, the Installer framework helpfully removes these files that are no longer part of the package&#8217;s payload. In other words, if you install file <code class="codecolorer text solarized-light"><span class="text">/usr/local/bin/my_script</span></code> in version 1, and instead only <code class="codecolorer text solarized-light"><span class="text">/usr/local/bin/my_new_script</span></code> in version 2, <code class="codecolorer text solarized-light"><span class="text">my_script</span></code> will be deleted if it was present when version 2 was installed, assuming that this package identifier is still known to the package database. (It wouldn&#8217;t be if, for example, <code class="codecolorer text solarized-light"><span class="text">pkgutil --forget my.package.identifier</span></code> was ever run manually or by an installer script).</p>
<p>We can use the built-in pkgutil tool to query the package database for metadata about packages (BOMs, identifiers, versions, etc.). To examine what package installed pkgbuild, for example, on this OS X 10.8.2 system:</p>
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">➜ &nbsp;~ &nbsp;pkgutil --file-info /usr/bin/pkgbuild<br />
<br />
volume: /<br />
path: /usr/bin/pkgbuild<br />
<br />
pkgid: com.apple.pkg.BSD<br />
pkg-version: 10.8.0.1.1.1306847324<br />
install-time: 1351028588<br />
uid: 0<br />
gid: 0<br />
mode: 755</div></div>
<p><code class="codecolorer text solarized-light"><span class="text">com.apple.pkg.BSD</span></code> is part of a standard OS X install.</p>
<p>One curious PackageInfo element <a href="http://s.sudre.free.fr/Stuff/Ivanhoe/FLAT.html">documented by Stéphane Sudre</a> is the <code class="codecolorer text solarized-light"><span class="text">dont-obsolete</span></code> element. As its name might suggest, &#8220;obsoleting&#8221; seems to be responsible for removing these files that are no longer present in upgraded package versions.</p>
<p>A real-world example: We recently had an internal support package included in our thin deployment image, one of whose payload items contained a template configuration file that was modified later as part of our DeployStudio workflow. I updated this support package with newer versions of unrelated components to be imported into <a href="http://code.google.com/p/munki">Munki</a> to push out to clients automatically, wanted to <em>not</em> overwrite this file when Munki would automatically install the package, and at the same time not remove the old one. The <code class="codecolorer text solarized-light"><span class="text">dont-obsolete</span></code> element turns out to be one solution to solve this problem within the logic of the package payload itself, without requiring workarounds in postinstall scripts that could potentially cause issues and greater complexity in the long term.</p>
<p>We can use the undocumented (but documented <a href="http://managingosx.wordpress.com/2012/07/05/stupid-tricks-with-pkgbuild">here</a> by Greg Neagle) <code class="codecolorer text solarized-light"><span class="text">--info</span></code> option for pkgbuild to supply the <code class="codecolorer text solarized-light"><span class="text">dont-obsolete</span></code> element to be included in the final built <code class="codecolorer text solarized-light"><span class="text">PackageInfo</span></code> file, using a template <code class="codecolorer text solarized-light"><span class="text">PackageInfo</span></code> that looks like this:</p>
<div class="codecolorer-container xml solarized-light" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;pkg-info<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dont-obsolete<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;file</span> <span style="color: #000066;">path</span>=<span style="color: #ff0000;">&quot;/usr/local/bin/my_script&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dont-obsolete<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/pkg-info<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></div>
<p>And to build the package:</p>
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">pkgbuild --identifier my.package.identifier \<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;--version 2.0 \<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;--root /my/payload/root \<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;--info /my/template/pkginfo-file \<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;my_support_package-2.0.pkg</div></div>
<p>Assuming the package we&#8217;re upgrading uses the same identifier and is a lower version number, this should do what we want, which is to persist the file at <code class="codecolorer text solarized-light"><span class="text">/usr/local/bin/my_script</span></code> after the installation, even if it&#8217;s not included in the 2.0 version of our package.</p>
<p>Instead of using the <code class="codecolorer text solarized-light"><span class="text">--info</span></code> option, we could also build the package without it, then later use pkgutil with the <code class="codecolorer text solarized-light"><span class="text">--expand</span></code> option, edit the PackageInfo file manually and finally <code class="codecolorer text solarized-light"><span class="text">--flatten</span></code> it as I documented in this <a href="http://macops.ca/xcode-deployment-the-dvtdownloadableindex-and-ios-simulators/" title="Xcode deployment: The dvtdownloadableindex and iOS Simulators/SDKs">earlier post on iOS Simulators</a>. This is of course much more work, but is easily automated.</p>
<p>Two asides:</p>
<p>pkgbuild also includes a useful <code class="codecolorer text solarized-light"><span class="text">--prior [pkg-path]</span></code> option, which will automatically derive the identifier, version and install-location parameters from a package located at <code class="codecolorer text solarized-light"><span class="text">pkg-path</span></code>. According to the pkgbuild manpage, however, this will convert the version number to an integer and increment it, which may not be what you want.</p>
<p>Also, there are some exceptions to when files are actually &#8220;obsoleted&#8221;. For example, removing old files will not necessarily occur if the <code class="codecolorer text solarized-light"><span class="text">PackageInfo</span></code> file has <code class="codecolorer text solarized-light"><span class="text">bundle-version</span></code> elements defined, which would happen if one is packaging, for example, an application bundle. Using pkgbuild with the <code class="codecolorer text solarized-light"><span class="text">--root</span></code> option will perform some analysis on the contents to extract bundle versions and place these in the <code class="codecolorer text solarized-light"><span class="text">PackageInfo</span></code> file. Look into the <code class="codecolorer text solarized-light"><span class="text">--analyze</span></code> and <code class="codecolorer text solarized-light"><span class="text">--component-plist</span></code> plist options in the pkgbuild <a href="https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man1/pkgbuild.1.html">manpage</a> to customize these further. Managing bundle metadata with the pkgbuild and productbuild tools is quite a bit more advanced, so the example in this post is mainly useful for application/site-specific data in simple files.</p>
]]></content:encoded>
			<wfw:commentRss>http://macops.ca/flat-packages-persisting-obsolescence/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Customizing hardware model filters for NetBoot</title>
		<link>http://macops.ca/customizing-hardware-model-filters-for-netboot/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=customizing-hardware-model-filters-for-netboot</link>
		<comments>http://macops.ca/customizing-hardware-model-filters-for-netboot/#comments</comments>
		<pubDate>Fri, 07 Dec 2012 02:19:03 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[DeployStudio]]></category>
		<category><![CDATA[NetBoot]]></category>
		<category><![CDATA[VMware Fusion]]></category>

		<guid isPermaLink="false">http://macops.ca/?p=198</guid>
		<description><![CDATA[Until the release of Lion, differentiating NetBoot images for DeployStudio Runtime to support different models was fairly simple. You&#8217;d have a Universal 10.5 image for booting PowerPC machines, and a 10.6 Intel image for Intel machines. Then Lion was released, and supported nearly every Intel Mac, leaving only the first generation models with 32-bit Core [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://macops.ca/wp-content/uploads/2012/12/XSNetInstall_256_crush.png"><img src="http://macops.ca/wp-content/uploads/2012/12/XSNetInstall_256_crush.png" alt="" title="XSNetInstall_256_crush" width="256" height="256" class="alignleft size-full wp-image-218" /></a>Until the release of Lion, differentiating NetBoot images for DeployStudio Runtime to support different models was fairly simple. You&#8217;d have a Universal 10.5 image for booting PowerPC machines, and a 10.6 Intel image for Intel machines.</p>
<p>Then Lion was released, and supported <em>nearly</em> every Intel Mac, leaving only the first generation models with <a href="http://en.wikipedia.org/wiki/Intel_Core#Enhanced_Pentium_M_based">32-bit Core</a> processors behind. Then Mountain Lion was released, and the compatibility matrix became more complex. With Apple announcing at the same time that they would be releasing a major new version of OS X every year, we can expect this trend to continue, and that we&#8217;ll need to know exactly which models can boot which versions of OS X. We&#8217;ll take a look at how we can offload this decision to the NetBoot server to make the process as simple as possible on the client end.</p>
<p><span id="more-198"></span></p>
<h3>Enter model filtering</h3>
<p>NetBoot has had support for model filtering for some time, which allows you to filter what models of Mac will be allowed to boot a given image via the NetBoot service. The goal is that you can maintain multiple OS versions of an installation or utility NetBoot image (like DeployStudio&#8217;s Runtime image) and let the server handle offering the version that a client can actually boot. NetBoot allows you to specify a &#8216;default&#8217; image, which can be useful for older Intel Macs whose EFI firmware doesn&#8217;t support selecting from multiple NetBoot images, but the end goal is that someone can hold the &#8216;N&#8217; key to NetBoot a machine and not need to know what OS they need to boot what hardware.</p>
<p>DeployStudio recently added a new feature in its Assistant application (which effectively drives the <code class="codecolorer text solarized-light"><span class="text">sys_builder.sh</span></code> script contained within its application bundle) for configuring NetBoot Runtime images to support hardware model filtering. Specifically, they needed to add the <code class="codecolorer text solarized-light"><span class="text">DisabledSystemIdentifiers</span></code> and <code class="codecolorer text solarized-light"><span class="text">EnabledSystemIdentifiers</span></code> arrays to the <code class="codecolorer text solarized-light"><span class="text">NBImageInfo.plist</span></code> which resides at the root of the resulting <code class="codecolorer text solarized-light"><span class="text">.nbi</span></code> folder. Even if these are empty arrays, the Server GUI will enable the editing of model filtering once these keys are present.</p>
<p>One downside to Apple&#8217;s provided GUI for the NetBoot service is that this database of Mac models is only kept up to date for the lifespan of that version of Server. For example, if you are still hosting NetBoot on Snow Leopard Server, you can&#8217;t instruct the service via the GUI to whitelist a 10.8 image to a 2012 MacBook Pro, because this model metadata was never backported to Server Admin for 10.6. In fact, it&#8217;s the last month of 2012 and I can&#8217;t find metadata pertaining to <em>any</em><br />
2012 Mac in the most recent versions of OS X Server for both Lion and Mountain Lion (and as of Mountain Lion Server, NetBoot is now NetInstall).</p>
<div id="attachment_209" class="wp-caption alignnone" style="width: 875px"><a href="http://macops.ca/wp-content/uploads/2012/12/netinstall-modelfilter_crush.png"><img src="http://macops.ca/wp-content/uploads/2012/12/netinstall-modelfilter_crush.png" alt="" title="netinstall-modelfilter_crush" width="865" height="624" class="size-full wp-image-209" /></a><p class="wp-caption-text">As of December 2012, no hardware more recent than &#8220;Early 2011&#8243;</p></div>
<h3>Configuration</h3>
<p>The model filtering selections are stored using hardware model identifiers (in the familiar style &#8216;iMac10,1&#8242;, &#8216;MacBookAir4,1&#8242;) in the <code class="codecolorer text solarized-light"><span class="text">NBImageInfo.plist</span></code> file. You can edit this file directly as it&#8217;s in XML format, though you should probably work off a copy for safety. You may also need to restart the NetBoot service in order for it to reload the changes.</p>
<p>For my environment, I decided to offer two NetBoot Runtime images: one for 10.6 to cover all older hardware, and a 10.8 image for all other Macs. Here&#8217;s my current <code class="codecolorer text solarized-light"><span class="text">NBImageInfo.plist</span></code> for the 10.8 image:</p>
<div class="codecolorer-container xml solarized-light" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:400px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;UTF-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span><br />
<span style="color: #00bbdd;">&lt;!DOCTYPE plist PUBLIC &quot;-//Apple//DTD PLIST 1.0//EN&quot; &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&gt;</span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;plist</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Architectures<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;array<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>i386<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/array<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>BackwardCompatible<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;false</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>BootFile<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>booter<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Description<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>DStudio-R134<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>DisabledSystemIdentifiers<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;array<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>iMac4,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>iMac4,2<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>iMac5,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>iMac5,2<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>iMac6,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>iMac7,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>iMac8,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBookAir1,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBookPro1,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBookPro2,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBookPro3,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBookPro4,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBook1,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBook2,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBook3,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBook4,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Macmini1,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Macmini2,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacPro1,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacPro2,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/array<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>EnabledSystemIdentifiers<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;array<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>iMac9,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>iMac10,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>iMac11,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>iMac11,2<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>iMac11,3<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>iMac12,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>iMac12,2<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBook5,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBook5,2<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBook6,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBook7,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBookAir2,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBookAir3,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBookAir3,2<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBookAir4,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBookAir4,2<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBookAir5,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBookAir5,2<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBookPro5,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBookPro5,2<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBookPro5,3<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBookPro5,4<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBookPro5,5<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBookPro6,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBookPro6,2<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBookPro7,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBookPro8,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBookPro8,2<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBookPro8,3<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBookPro9,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBookPro9,2<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBookPro10,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacBookPro10,2<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Macmini3,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Macmini4,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Macmini5,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Macmini5,2<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Macmini5,3<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacPro3,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacPro4,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>MacPro5,1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/array<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Index<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;integer<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>1082<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/integer<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>IsDefault<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;false</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>IsEnabled<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;true</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>IsInstall<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;true</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Kind<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;integer<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>2<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/integer<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Language<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>English<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Name<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>DeployStudio-10.8<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>RootPath<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NetInstall.dmg<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>SupportsDiskless<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;false</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Type<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NFS<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>osVersion<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>10.8<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/plist<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></div>
<p>My goal was to offer only one image for any given model I want to support, so here I&#8217;ve put each model in either one of <code class="codecolorer text solarized-light"><span class="text">DisabledSystemIdentifiers</span></code> or <code class="codecolorer text solarized-light"><span class="text">EnabledSystemIdentifiers</span></code> arrays (I&#8217;ve skipped Xserves, but I don&#8217;t think I&#8217;ve missed any others). The contents of these arrays are reversed in the 10.6 image, so that every model identifier is only enabled for one image. In the near future when we have 10.9-based images, it&#8217;s likely that we&#8217;ll still only require two generations of NetBoot images, but using this method we could have more if we desired.</p>
<p>Because this plist is per-image and it&#8217;s labour-intensive to build the lists of system identifiers, it would be a good idea to have backups of these lists to use as new versions of NetBoot sets are built for new versions of OS X and DeployStudio. Or, script adding them automatically after calling sys_builder.sh with pre-defined arguments.</p>
<h3>Sources of truth</h3>
<p>Apple makes use of the &#8216;board-id&#8217; to determine whether a version of OS X 10.7 or 10.8 can be installed on a given machine. This can be retrieved via the ioreg command (ie. <code class="codecolorer text solarized-light"><span class="text">ioreg -l | grep board-id</span></code>) and looks something like <code class="codecolorer text solarized-light"><span class="text">Mac-F4208CA9</span></code>. Lists of these board-ids are in the Distribution files for the OS installers, and are also in a plist at <code class="codecolorer text solarized-light"><span class="text">/System/Library/CoreServices/PlatformSupport.plist</span></code> within an <code class="codecolorer text solarized-light"><span class="text">InstallESD.dmg</span></code>. What&#8217;s also interesting is that as of OS X 10.7.5 and 10.8.1, this plist contains a second array called <code class="codecolorer text solarized-light"><span class="text">SupportedModelProperties</span></code>, which is a list of model identifiers. It would seem at first that perhaps this list could be directly mapped to the arrays we&#8217;re managing in the <code class="codecolorer text solarized-light"><span class="text">NBImageInfo.plist</span></code>. However, there are several hardware models missing from <code class="codecolorer text solarized-light"><span class="text">SupportedModelProperties</span></code> that I know are supported versions of the OS on those models, so unfortunately it looks like this isn&#8217;t a definitive list of models that&#8217;s used by installer, or at least not for determining eligibility for installation. A Mac will send its board-id and serial number to Apple via HTTP during <a href="http://support.apple.com/kb/HT4718">Internet Recovery</a>, but I&#8217;m not aware of a model-to-board-id mapping source anywhere. It&#8217;s possible that an organization with enough Macs could compile one itself.</p>
<p>For the many models that can boot both 10.6 and 10.8, there&#8217;s no systematic reason I had for choosing one OS version over another for a given model. You might have your own reasons – newer OS versions of Runtime NBIs have sometimes taken longer to support all workflow features, for example live package installs were not working for some time on Lion-based Runtime images.</p>
<h3>Testing with VMs</h3>
<p>Lastly, if you do implement this method and use VMware Fusion to test your NetBoot environment, your OS X VMs will not boot without a minor change. In Fusion 4.1, VMware added a <a href="http://communities.vmware.com/message/1865986">new configuration option</a> for VMs: <strong>hw.model.reflectHost</strong>. This option can be set in the VM&#8217;s <code class="codecolorer text solarized-light"><span class="text">.vmx</span></code> file located at the root of its <code class="codecolorer text solarized-light"><span class="text">.vmwarevm</span></code> folder, and passes the host&#8217;s hardware model string through to the VM. <a href="http://enterprisemac.bruienne.com">Pepijn Bruienne</a> also <a href="https://twitter.com/bruienne/status/263455723864875008">pointed out on Twitter</a> the <strong>hw.model</strong> configuration option, which is even better: it allows arbitrary model strings, which allows you to test that a specific model will boot the image you intend it to. You could also use this to test any installer or script logic that depends on hardware model identifiers (for example, hardware-specific Apple Software Updates).</p>
]]></content:encoded>
			<wfw:commentRss>http://macops.ca/customizing-hardware-model-filters-for-netboot/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Interfacing with DeployStudio using HTTP</title>
		<link>http://macops.ca/interfacing-with-deploystudio-using-http/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=interfacing-with-deploystudio-using-http</link>
		<comments>http://macops.ca/interfacing-with-deploystudio-using-http/#comments</comments>
		<pubDate>Sun, 02 Dec 2012 23:51:22 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[APIs]]></category>
		<category><![CDATA[curl]]></category>
		<category><![CDATA[DeployStudio]]></category>
		<category><![CDATA[PlistBuddy]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[vendor metadata]]></category>

		<guid isPermaLink="false">http://macops.ca/?p=159</guid>
		<description><![CDATA[DeployStudio is frequently a starting place for deploying and configuring Mac systems. It has a computer database that can store information like computer/host names, default workflows, management settings and custom properties that can be leveraged by workflow scripts and inventory systems. It&#8217;s well-known that all this database information is stored in plain XML plist files [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://macops.ca/interfacing-with-deploystudio-using-http/dsadmin-256/" rel="attachment wp-att-274"><img src="http://macops.ca/wp-content/uploads/2012/12/DSAdmin-256.png" alt="DSAdmin-256" width="256" height="256" class="alignleft size-full wp-image-274" /></a><a href="http://deploystudio.com">DeployStudio</a> is frequently a starting place for deploying and configuring Mac systems. It has a computer database that can store information like computer/host names, default workflows, management settings and custom properties that can be leveraged by workflow scripts and inventory systems.</p>
<p>It&#8217;s well-known that all this database information is stored in plain XML plist files in the DeployStudio repository, one per computer, named after the value of the computer&#8217;s primary key (serial number or MAC address). Sometimes people have wanted to manage this data from an external source like a web form or script that can be used by technicians deploying new hardware, but run up against the fact that changes to these files can only be loaded by restarting the DeployStudioServer service. That&#8217;s by design. These plists are DeployStudio&#8217;s database, and we don&#8217;t directly interact with an applications&#8217;s database if we can ever help it; that&#8217;s what APIs are for, and DeployStudio has a basic <a href="http://en.wikipedia.org/wiki/Representational_state_transfer">REST</a>-style API which it uses to perform all its communications between the server, admin client and runtime instances. This post will show some basic examples of how simple it is to interact with DeployStudio via command-line tools, and a Python example for setting arbitrary properties in the computer database.</p>
<p><span id="more-159"></span><br />
Navigate to http[s]://your.deploystudio.server:port in your browser and fill in your credentials for a user with rights to DeployStudio Admin. You&#8217;ll see a list of methods, the left-hand column using GET for retrieving values, the right-hand column using POST for setting values.</p>
<table border="0">
<tr>
<td>GET methods:</td>
<td>POST methods:</td>
</tr>
<tr>
<td>/computers/get/all</td>
<td>/computers/del/entries</td>
</tr>
<tr>
<td>/computers/get/entry</td>
<td>/computers/del/entry</td>
</tr>
<tr>
<td>/computers/groups/get/all</td>
<td>/computers/groups/del/default</td>
</tr>
<tr>
<td>&#8230;</td>
<td>&#8230;</td>
</tr>
</table>
<p>If you use a web debug tool like <a href="http://www.charlesproxy.com">Charles</a> to inspect your traffic going out to your DeployStudio server, you can pretty quickly get a sense of what&#8217;s going on. For example, when DeployStudio Admin connects to your repo, one of its requests is to <code class="codecolorer text solarized-light"><span class="text">/computers/get/all</span></code>, which will retrieve all computer database information that the Admin app will use to populate its various text fields and table view. This information comes in the same form it&#8217;s stored, as XML plists, and your Admin client is sending changes back out in that format as well. Only difference is that instead of editing plist files on disk, DeployStudio Admin is making an HTTP request and sending the XML plist data using the POST method. There are some subtleties to account for in the contents of these plists, but it&#8217;s fairly straightforward.</p>
<p>We can use <code class="codecolorer text solarized-light"><span class="text">curl</span></code> to take a look at the structure of what&#8217;s received. DeployStudio uses HTTP Basic Auth everywhere, so you can have curl encode the appropriate header with the <code class="codecolorer text solarized-light"><span class="text">-u username:password</span></code> option, or leave out the <code class="codecolorer text solarized-light"><span class="text">:password</span></code> component and it will prompt you. We&#8217;re also using the <code class="codecolorer text solarized-light"><span class="text">-k</span></code> option because in these examples we&#8217;re connecting using SSL and want to bypass the warning that DeployStudio is using a self-signed certificate. We can fetch all available computer info using the <code class="codecolorer text solarized-light"><span class="text">/computers/get/all</span></code> endpoint and save it to a file at <code class="codecolorer text solarized-light"><span class="text">out.plist</span></code>:</p>
<div class="codecolorer-container bash solarized-light" style="border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">curl <span style="color: #660033;">-u</span> testdsuser <span style="color: #660033;">-k</span> https:<span style="color: #000000; font-weight: bold;">//</span>my.ds.repo:<span style="color: #000000;">60443</span><span style="color: #000000; font-weight: bold;">/</span>computers<span style="color: #000000; font-weight: bold;">/</span>get<span style="color: #000000; font-weight: bold;">/</span>all <span style="color: #000000; font-weight: bold;">&gt;</span> out.plist</div></div>
<p>Opening it up, this is how it looks:</p>
<div class="codecolorer-container xml solarized-light" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:400px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;UTF-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span><br />
<span style="color: #00bbdd;">&lt;!DOCTYPE plist PUBLIC &quot;-//Apple//DTD PLIST 1.0//EN&quot; &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&gt;</span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;plist</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>computers<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>DOUGLASFIRS<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>cn<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>diane<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-auto-disable<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-auto-reset-workflow<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-custom-properties<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;array<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-custom-property-key<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>ASSET_TAG<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-custom-property-label<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>My Great Asset Tag<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-custom-property-value<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>BL4CKL0DG3<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/array<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-disabled<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-ard-ignore-empty-fields<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-delete-other-locations<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-interfaces<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>en0<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-dns-ips<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-airport<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-airport-name<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-airport-password<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-auto-config-proxy<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-auto-config-proxy-url<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-auto-discovery-proxy<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-ftp-proxy<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-ftp-proxy-port<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-ftp-proxy-server<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-http-proxy<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-http-proxy-port<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-http-proxy-server<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-https-proxy<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-https-proxy-port<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-https-proxy-server<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-interfaces<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>en0<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-ip<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-router-ip<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-search-domains<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-subnet-mask<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-new-network-location<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-primary-key<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-serial-number<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-serial-number<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>DOUGLASFIRS<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-hostname<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>diane<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>HOWSANNIE<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>cn<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>my-great-mac<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-auto-disable<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-auto-reset-workflow<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-disabled<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-ard-ignore-empty-fields<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-delete-other-locations<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-interfaces<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>en0<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-dns-ips<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-airport<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-airport-name<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-airport-password<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-auto-config-proxy<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-auto-config-proxy-url<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-auto-discovery-proxy<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-ftp-proxy<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-ftp-proxy-port<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-ftp-proxy-server<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-http-proxy<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-http-proxy-port<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-http-proxy-server<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-https-proxy<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-https-proxy-port<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-https-proxy-server<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-interfaces<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>en0<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-ip<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-router-ip<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-search-domains<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-subnet-mask<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-new-network-location<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-primary-key<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-serial-number<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-serial-number<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>HOWSANNIE<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-hostname<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>my-great-mac<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>groups<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/plist<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></div>
<p>In the XML returned, the <code class="codecolorer text solarized-light"><span class="text">computers</span></code> dictionary contains dictionaries each named by the computer ID, either a serial number or a MAC address. Here we have <code class="codecolorer text solarized-light"><span class="text">DOUGLASFIRS</span></code> and <code class="codecolorer text solarized-light"><span class="text">HOWSANNIE</span></code>. In this example we&#8217;ll look mainly at the serial number, computer name and hostname (<code class="codecolorer text solarized-light"><span class="text">dstudio-host-serial-number</span></code>, <code class="codecolorer text solarized-light"><span class="text">cn</span></code> and <code class="codecolorer text solarized-light"><span class="text">dstudio-hostname</span></code>keys, respectively), but there&#8217;s lots of other empty fields, particularly all the networking-related information.</p>
<p>Say we want to just rename the <code class="codecolorer text solarized-light"><span class="text">DOUGLASFIRS</span></code> computer, by changing its computer name and local host name to &#8216;diane&#8217;. (While I don&#8217;t typically use hostnames for anything, the hostname has the privilege of being one of the few columns available in DeployStudio Admin for identifying a computer in the list.) We&#8217;ll use PlistBuddy to change the <code class="codecolorer text solarized-light"><span class="text">cn</span></code> and <code class="codecolorer text solarized-light"><span class="text">dstudio-hostname</span></code> keys in the plist we just output:</p>
<div class="codecolorer-container bash solarized-light" style="border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>libexec<span style="color: #000000; font-weight: bold;">/</span>PlistBuddy <span style="color: #660033;">-c</span> <span style="color: #ff0000;">&quot;Set :computers:DOUGLASFIRS:cn diane&quot;</span> out.plist<br />
<span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>libexec<span style="color: #000000; font-weight: bold;">/</span>PlistBuddy <span style="color: #660033;">-c</span> <span style="color: #ff0000;">&quot;Set :computers:DOUGLASFIRS:dstudio-hostname diane&quot;</span> out.plist</div></div>
<p>There&#8217;s one more detail to take care of. We&#8217;re going to send this updated computer record plist to the server using POST to the <code class="codecolorer text solarized-light"><span class="text">/computers/set/entry</span></code> endpoint, but this endpoint expects to be passed only the contents of a single computer dict, using an <code class="codecolorer text solarized-light"><span class="text">id</span></code> parameter to identify the record we&#8217;re modifying. So in order to simplify our XML slightly and only send the contents of the <code class="codecolorer text solarized-light"><span class="text">DOUGLASFIRS</span></code> dict, we&#8217;ll again use PlistBuddy – this time using the <code class="codecolorer text solarized-light"><span class="text">-x</span></code> parameter to output in plist format – to retrieve just the nested <code class="codecolorer text solarized-light"><span class="text">DOUGLASFIRS</span></code> dict, and write this out to a new file at <code class="codecolorer text solarized-light"><span class="text">douglasfirs-renamed.plist</span></code>:</p>
<div class="codecolorer-container bash solarized-light" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>libexec<span style="color: #000000; font-weight: bold;">/</span>PlistBuddy <span style="color: #660033;">-x</span> <span style="color: #660033;">-c</span> <span style="color: #ff0000;">&quot;Print :computers:DOUGLASFIRS&quot;</span> out.plist <span style="color: #000000; font-weight: bold;">&gt;</span> douglasfirs-renamed.plist</div></div>
<p>We could just have easily done all this with a text editor, but I&#8217;m using PlistBuddy because it&#8217;s one way these kinds of changes could be made automatically via a script rather than manually. Now our updated computer info in <code class="codecolorer text solarized-light"><span class="text">douglasfirs-renamed</span></code> looks like this:</p>
<div class="codecolorer-container xml solarized-light" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:400px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;UTF-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span><br />
<span style="color: #00bbdd;">&lt;!DOCTYPE plist PUBLIC &quot;-//Apple//DTD PLIST 1.0//EN&quot; &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&gt;</span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;plist</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>cn<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>diane<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-auto-disable<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-auto-reset-workflow<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-custom-properties<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;array<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-custom-property-key<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>ASSET_TAG<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-custom-property-label<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>My Great Asset Tag<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-custom-property-value<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>BL4CKL0DG3<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/array<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-disabled<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-ard-ignore-empty-fields<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-delete-other-locations<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-interfaces<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>en0<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-dns-ips<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-airport<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-airport-name<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-airport-password<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-auto-config-proxy<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-auto-config-proxy-url<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-auto-discovery-proxy<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-ftp-proxy<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-ftp-proxy-port<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-ftp-proxy-server<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-http-proxy<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-http-proxy-port<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-http-proxy-server<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-https-proxy<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-https-proxy-port<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-https-proxy-server<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-interfaces<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>en0<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-ip<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-router-ip<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-search-domains<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-subnet-mask<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-new-network-location<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>NO<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-primary-key<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-serial-number<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-host-serial-number<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>DOUGLASFIRS<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dstudio-hostname<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>diane<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/plist<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></div>
<p>We&#8217;re ready to commit these changes back to DeployStudio, so we&#8217;ll again use curl to POST the data using the <code class="codecolorer text solarized-light"><span class="text">--data</span></code> option and prepend the file with an <code class="codecolorer text solarized-light"><span class="text">@</span></code> symbol to specify we want to feed it the contents of the file:</p>
<div class="codecolorer-container bash solarized-light" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">curl <span style="color: #660033;">-k</span> <span style="color: #660033;">-u</span> testdsuser <span style="color: #660033;">--data</span> <span style="color: #000000; font-weight: bold;">@</span>douglasfirs-renamed.plist <span style="color: #ff0000;">&quot;https://my.ds.repo:60443/computers/set/entry?id=DOUGLASFIRS&quot;</span></div></div>
<p>The same endpoint is used if we want to create a new record &#8211; we would just format a new computer plist containing the fields we care about and submit it using the appropriate ID. A new record need not contain all these blank placeholder keys; a new computer record created in DeployStudio Admin will only contain <code class="codecolorer text solarized-light"><span class="text">dstudio-host-primary-key</span></code> and one of <code class="codecolorer text solarized-light"><span class="text">dstudio-host-serial-number</span></code> or <code class="codecolorer text solarized-light"><span class="text">dstudio-mac-addr</span></code>. It&#8217;s important to know that these other keys can exist (and definitely <em>will</em> if the record has ever been modified in Admin), because a plist sent to this endpoint will completely overwrite the existing plist. Therefore, if one is modifying an existing record and wants to preserve any other values that may be contained in the record, one should always fetch the existing record and make changes. This is why we used PlistBuddy above to copy the individual computer dict from the existing data out to a new plist.</p>
<p>One other thing to note if you&#8217;re testing this and not seeing the changes in DeployStudio Admin: in order to get the changes to the computer database, DeployStudio Admin needs to do another GET to <code class="codecolorer text solarized-light"><span class="text">/computers/get/all</span></code>, which can  be triggered by switching to a different section in the left-hand sidebar. DeployStudio Admin is not refreshing all the computer information periodically, likely because it expects to be the only application editing it and it&#8217;s already keeping track internally of local edits.</p>
<p>I used curl and PlistBuddy because they&#8217;re capable tools that any seasoned Mac admin is familiar with. There&#8217;s certainly nothing wrong with using them in this context, although a higher-level scripting language like Python is particularly well-suited to this task for a couple reasons. It has a built-in module to handle XML plist data as native Python dictionaries, meaning no dealing with PlistBuddy or defaults and their esoteric syntaxes is required. It ships with a great standard library of modules that can perform all this functionality without requiring a shell or external (platform-specific) binaries. This also means any code written in Python using these built-in modules can be ported to a web application running on Linux or Windows with few or no changes.</p>
<p>Here&#8217;s a short Python example of a couple simple operations using the same endpoints we used above, as well as manipulating a custom property representing an organization&#8217;s asset tag. The <code class="codecolorer text solarized-light"><span class="text">updateHostProperties()</span></code> function allows us to specify a computer ID and a dictionary of properties we&#8217;d like to change. It transparently handles creating a new record if one doesn&#8217;t already exist. There&#8217;s a lot of room to improve its robustness as it performs no real error handling, but this is omitted to keep the example shorter. The two example operations it performs can be found commented in the <code class="codecolorer text solarized-light"><span class="text">main()</span></code> function at the end, and with each invocation it will simply generate a new computer/hostname of the form &#8216;random-id-n&#8217;.</p>
<div class="codecolorer-container python solarized-light" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:400px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br />88<br />89<br />90<br />91<br />92<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #808080; font-style: italic;">#!/usr/bin/python</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">urllib2</span><br />
<span style="color: #ff7700;font-weight:bold;">import</span> plistlib<br />
<span style="color: #ff7700;font-weight:bold;">from</span> <span style="color: #dc143c;">random</span> <span style="color: #ff7700;font-weight:bold;">import</span> randrange<br />
<br />
host <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'https://my.ds.repo:60443'</span><br />
adminuser <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'testdsuser'</span><br />
adminpass <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'12345'</span><br />
<br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> setupAuth<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #483d8b;">&quot;&quot;&quot;Install an HTTP Basic Authorization header globally so it's used for<br />
every request.&quot;&quot;&quot;</span><br />
&nbsp; &nbsp; auth_handler <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">HTTPBasicAuthHandler</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; auth_handler.<span style="color: black;">add_password</span><span style="color: black;">&#40;</span>realm<span style="color: #66cc66;">=</span><span style="color: #483d8b;">'DeployStudioServer'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; uri<span style="color: #66cc66;">=</span>host<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #dc143c;">user</span><span style="color: #66cc66;">=</span>adminuser<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; passwd<span style="color: #66cc66;">=</span>adminpass<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; opener <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">build_opener</span><span style="color: black;">&#40;</span>auth_handler<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">install_opener</span><span style="color: black;">&#40;</span>opener<span style="color: black;">&#41;</span><br />
<br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> getHostData<span style="color: black;">&#40;</span>machine_id<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #483d8b;">&quot;&quot;&quot;Return the full plist for a computer entry&quot;&quot;&quot;</span><br />
&nbsp; &nbsp; machine_data <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">urlopen</span><span style="color: black;">&#40;</span>host + <span style="color: #483d8b;">'/computers/get/entry?id=%s'</span> % machine_id<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; plist <span style="color: #66cc66;">=</span> plistlib.<span style="color: black;">readPlistFromString</span><span style="color: black;">&#40;</span>machine_data.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># if id isn't found, result will be an empty plist</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> plist<br />
<br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> updateHostProperties<span style="color: black;">&#40;</span>machine_id<span style="color: #66cc66;">,</span> properties<span style="color: #66cc66;">,</span> key_mac_addr<span style="color: #66cc66;">=</span><span style="color: #008000;">False</span><span style="color: #66cc66;">,</span> create_new<span style="color: #66cc66;">=</span><span style="color: #008000;">False</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #483d8b;">&quot;&quot;&quot;Update the computer at machine_id with properties, a dict of properties and<br />
values we want to set with new values. Return the full addinfourl object or None<br />
if we found no computer to update and we aren't creating a new one. Set create_new<br />
to True in order to enable creating new entries.&quot;&quot;&quot;</span><br />
&nbsp; &nbsp; found_comp <span style="color: #66cc66;">=</span> getHostData<span style="color: black;">&#40;</span>machine_id<span style="color: black;">&#41;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># If we found no computer and we don't want a new record created</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> found_comp <span style="color: #ff7700;font-weight:bold;">and</span> <span style="color: #ff7700;font-weight:bold;">not</span> create_new:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #008000;">None</span><br />
<br />
&nbsp; &nbsp; new_data <span style="color: #66cc66;">=</span> <span style="color: black;">&#123;</span><span style="color: black;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> found_comp:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Computer data comes back as plist nested like: {'SERIALNO': {'cn': 'my-name'}}</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># DeployStudioServer expects a /set/entry POST like: {'cn': 'my-new-name'}</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># so we copy the keys up a level</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; update <span style="color: #66cc66;">=</span> <span style="color: #008000;">dict</span><span style="color: black;">&#40;</span><span style="color: black;">&#40;</span>k<span style="color: #66cc66;">,</span> v<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> <span style="color: black;">&#40;</span>k<span style="color: #66cc66;">,</span> v<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">in</span> found_comp<span style="color: black;">&#91;</span>machine_id<span style="color: black;">&#93;</span>.<span style="color: black;">items</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; new_data <span style="color: #66cc66;">=</span> update.<span style="color: #dc143c;">copy</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># No computer exists for this ID, we need to set up two required keys:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># 'dstudio-host-primary-key' and one of 'dstudio-host-serial-number'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># or 'dstudio-mac-addr' is required, otherwise request is ignored</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># - IOW: you can't only rely on status codes</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># - primary key is a server-level config, but we seem to need this per-host</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> key_mac_addr:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new_data<span style="color: black;">&#91;</span><span style="color: #483d8b;">'dstudio-host-primary-key'</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'dstudio-mac-addr'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new_data<span style="color: black;">&#91;</span><span style="color: #483d8b;">'dstudio-host-primary-key'</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'dstudio-host-serial-number'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; new_data<span style="color: black;">&#91;</span>new_data<span style="color: black;">&#91;</span><span style="color: #483d8b;">'dstudio-host-primary-key'</span><span style="color: black;">&#93;</span><span style="color: black;">&#93;</span> <span style="color: #66cc66;">=</span> machine_id<br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> <span style="color: black;">&#40;</span>k<span style="color: #66cc66;">,</span> v<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">in</span> properties.<span style="color: black;">items</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; new_data<span style="color: black;">&#91;</span>k<span style="color: black;">&#93;</span> <span style="color: #66cc66;">=</span> v<br />
&nbsp; &nbsp; plist_to_post <span style="color: #66cc66;">=</span> plistlib.<span style="color: black;">writePlistToString</span><span style="color: black;">&#40;</span>new_data<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; result <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">urllib2</span>.<span style="color: black;">urlopen</span><span style="color: black;">&#40;</span>host + <span style="color: #483d8b;">'/computers/set/entry?id='</span> + machine_id<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; plist_to_post<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> result<br />
<br />
<br />
<span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; setupAuth<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Update HOWSANNIE with a new computer name (assuming this entry already exists)</span><br />
&nbsp; &nbsp; random_name <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'random-id-'</span> + <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>randrange<span style="color: black;">&#40;</span><span style="color: #ff4500;">100</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; result <span style="color: #66cc66;">=</span> updateHostProperties<span style="color: black;">&#40;</span><span style="color: #483d8b;">'HOWSANNIE'</span><span style="color: #66cc66;">,</span> <span style="color: black;">&#123;</span><span style="color: #483d8b;">'cn'</span>: random_name<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'dstudio-hostname'</span>: random_name<span style="color: black;">&#125;</span><span style="color: black;">&#41;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># Update DOUGLASFIRS with a new computername and custom properties, or create</span><br />
&nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># it if it doesn't already exist</span><br />
&nbsp; &nbsp; random_name <span style="color: #66cc66;">=</span> <span style="color: #483d8b;">'random-id-'</span> + <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>randrange<span style="color: black;">&#40;</span><span style="color: #ff4500;">100</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; updateHostProperties<span style="color: black;">&#40;</span><span style="color: #483d8b;">'DOUGLASFIRS'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#123;</span><span style="color: #483d8b;">'cn'</span>: random_name<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'dstudio-hostname'</span>: random_name<span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'dstudio-custom-properties'</span>: <span style="color: black;">&#91;</span><span style="color: black;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'dstudio-custom-property-key'</span>: <span style="color: #483d8b;">'ASSET_TAG'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'dstudio-custom-property-label'</span>: <span style="color: #483d8b;">'My Great Asset Tag'</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">'dstudio-custom-property-value'</span>: <span style="color: #483d8b;">'BL4CKL0DG3'</span><span style="color: black;">&#125;</span><span style="color: black;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#125;</span><span style="color: #66cc66;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; create_new<span style="color: #66cc66;">=</span><span style="color: #008000;">True</span><span style="color: black;">&#41;</span><br />
<br />
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ <span style="color: #66cc66;">==</span> <span style="color: #483d8b;">&quot;__main__&quot;</span>:<br />
&nbsp; &nbsp; main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
]]></content:encoded>
			<wfw:commentRss>http://macops.ca/interfacing-with-deploystudio-using-http/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Xcode deployment: The dvtdownloadableindex and iOS Simulators/SDKs</title>
		<link>http://macops.ca/xcode-deployment-the-dvtdownloadableindex-and-ios-simulators/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=xcode-deployment-the-dvtdownloadableindex-and-ios-simulators</link>
		<comments>http://macops.ca/xcode-deployment-the-dvtdownloadableindex-and-ios-simulators/#comments</comments>
		<pubDate>Mon, 19 Nov 2012 13:45:19 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[flat packages]]></category>
		<category><![CDATA[iOS SDK]]></category>
		<category><![CDATA[pkgutil]]></category>
		<category><![CDATA[vendor metadata]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://macops.ca/?p=96</guid>
		<description><![CDATA[Around the time of the release of OS X Mountain Lion, Xcode moved to a single drag &#8216;n drop .dmg model to simplify the user installation experience, and Apple was nice enough to make the Command Line tools a separate download. Unfortunately, this hasn&#8217;t simplified the process of mass deployment, and we now have more [...]]]></description>
				<content:encoded><![CDATA[<p><img src="http://macops.ca/wp-content/uploads/2012/11/xcode_IDEDownloadsIcon_64.png" alt="" title="xcode_IDEDownloadsIcon_64" width="64" height="64" class="alignleft size-full wp-image-156" />Around the time of the release of OS X Mountain Lion, Xcode moved to a single drag &#8216;n drop .dmg model to simplify the user installation experience, and Apple was nice enough to make the Command Line tools a separate download. Unfortunately, this hasn&#8217;t simplified the process of mass deployment, and we now have more moving pieces to keep track of than ever before. Anyone who&#8217;s deployed Xcode recently may be familiar with its laundry list of post-installation tasks.</p>
<p>Some downloads, like the Command-Line Tools and earlier iOS Simulator/SDK versions, show up in a new &#8220;Components&#8221; download area located in Xcode&#8217;s Preferences. We&#8217;ll look at where this index comes from, how we can inspect it to get the iOS simulator .dmg download URLs, and one method of modifying the simulator installer packages so that they install to the correct location via any standard package distribution method like Munki or Casper. If you manage installing the Command-Line Tools as well, you&#8217;ll find metadata here that will help with tracking version installs (anyone who&#8217;s tried to manage deploying/updating them knows they <em>don&#8217;t</em> use Apple package versioning).</p>
<div id="attachment_127" class="wp-caption alignnone" style="width: 874px"><a href="http://macops.ca/wp-content/uploads/2012/11/xcode-4.5.2-dvt.png"><img class="size-full wp-image-127" title="xcode-4.5.2-dvt" src="http://macops.ca/wp-content/uploads/2012/11/xcode-4.5.2-dvt.png" alt="" width="864" height="662" /></a><p class="wp-caption-text">Xcode Preferences: Downloads</p></div>
<p>We&#8217;ll also quickly review the other steps typically required to &#8220;finalize&#8221; the Xcode installation for most deployment scenarios. Big thanks to <a href="http://afp548.com/author/natewalck">Nate Walck</a> for testing what I&#8217;d originally documented for the iOS Simulator installation and determining that I&#8217;d skipped an important step!</p>
<p><span id="more-96"></span></p>
<p>Deploying Xcode via a software management mechanism such as Munki, Casper or ARD usually requires a few steps for a fully-functional install. These usually include:</p>
<ul>
<li>copy the Xcode.app bundle from the .dmg to /Applications</li>
<li>copy out the MobileDevice.pkg (and MobileDeviceDevelopment.pkg as of Xcode 4.5) from Xcode.app/Contents/Resources/Packages and install them separately</li>
<li>assuming your users are not admins, adding an appropriate user group to the _developer group, and running <code class="codecolorer text solarized-light"><span class="text">/usr/sbin/DevToolsSecurity -enable</span></code>, which handles modifying the security policies in <code class="codecolorer text solarized-light"><span class="text">/etc/authorization</span></code></li>
<li>optionally install the Command Line Tools for the appropriate OS version</li>
<li>optionally accept EULAs and configure the options for downloading extra components and documentation, via the defaults domain at <code class="codecolorer text solarized-light"><span class="text">com.apple.dt.Xcode</span></code></li>
</ul>
<p>Installing these additional components has been already <a href="http://derflounder.wordpress.com/2012/07/26/building-a-grand-unified-xcode-4-4-installer-for-both-lion-and-mountain-lion">documented</a> <a href="http://code.google.com/p/munki/wiki/Xcode">in</a> <a href="https://jamfnation.jamfsoftware.com/discussion.html?id=4034">several</a> <a href="https://groups.google.com/group/macenterprise/browse_frm/thread/7058446425120177">places</a>, but I hadn&#8217;t yet seen anyone describe how they deployed versions of the iOS Simulator/SDK, which normally would be an optional component download.</p>
<p>Xcode seems to automatically include the most current version of the SDK in its .app bundle, so this is primarily useful if you want to be able to deploy older versions as well. But if you manage Xcode it&#8217;s a good idea to become familiar with this index file anyway.</p>
<p>I recently discovered via the <a href="http://www.charleswebproxy.com">Charles web proxy</a> tool what Xcode actually downloads from Apple to populate its list of additional components for download, which is also used to determine how they&#8217;re installed. It turns out these indexes are also cached locally on the client, so no web traffic sniffing is even needed.</p>
<p>Once you&#8217;ve launched Xcode at least once as a user, head over to that user&#8217;s Xcode cached downloads folder at <code class="codecolorer text solarized-light"><span class="text">~/Library/Caches/com.apple.dt.Xcode/Downloads</span></code>.</p>
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">-rw-r--r--@ 147M 1 Jul 11:52 Xcode.CLTools.10.7-1.3.1.dmg<br />
-rw-r--r--@ 136M 11 Aug 22:24 Xcode.CLTools.10.7-4.4.1.3.2.dmg<br />
-rw-r--r--@ 137M 12 Nov 21:14 Xcode.CLTools.10.7-4.5.7.dmg<br />
-rw-r--r--@ 528M 17 Sep 00:10 Xcode.SDK.iPhoneSimulator.5.0-5.0.0.1.dmg<br />
-rw-r--r--@ 400K 17 Sep 00:11 Xcode.SDK.iPhoneSimulator.5.0-5.0.1.1.dmg<br />
-rw-r--r-- &nbsp; 12K 20 Oct 17:27 eded78df8bfabaf6560841d10cf8e53766f74f28.dvtdownloadableindex<br />
-rw-r--r-- &nbsp;8.3K &nbsp;9 Jul 19:43 f7133e82a08bdb4ebf724f16beed2bbac2a265cf.dvtdownloadableindex<br />
-rw-r--r-- &nbsp; 11K 13 Nov 21:28 f9556a99100ac5200138e50480d2471b6bdc4adc.dvtdownloadableindex</div></div>
<p>In mine, I have some cached downloads (which Xcode helpfully renamed to saner filenames than it stores on its downloads site), and a few different index files. Each one is from a different version of Xcode. On this machine I&#8217;ve gone from version 4.3 to 4.4. to 4.5, and I believe these index filenames remain the same for patch versions. The only one getting updated now is the last one dated Nov 13, f9556a&#8230;dvtdownloadableindex.</p>
<p>These cached versions are binary plists, so either first convert them to the XML plist format or open them an editor like <a href="http://barebones.com">TextWrangler</a> or <a href="https://github.com/textmate/textmate">TextMate</a>, which support transparent conversion of binary plists. If we open this up, we can see it serves a purpose similar to Apple&#8217;s Software Update .sucatalog files, except all its logic and metadata is inline. One item to take note of is the <code class="codecolorer text solarized-light"><span class="text">source</span></code> key at the bottom:</p>
<div class="codecolorer-container xml solarized-light" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">source<br />
https://devimages.apple.com.edgekey.net/downloads/xcode/simulators/index-3905972D-B609-49CE-8D06-51ADC78E07BC.dvtdownloadableindex</div></div>
<p>The GUID in this URL seems to be unique to the Xcode major version, as is the SHA-1 that makes up the filename stored in the local cache. A couple useful header values from the web server for this URL:</p>
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">ETag: &quot;b16e24a220cced60c26a1d0693c669fa:1351889685&quot;<br />
Last-Modified: Fri, 02 Nov 2012 20:54:45 GMT</div></div>
<p>The ETag in this case is an md5 of the file and the time it was modified in the <a href="http://en.wikipedia.org/wiki/Unix_time">Unix time format</a>. Given this, you could monitor changes to either of these headers to know when there may be new changes in the index. (Of course, this index URL would likely change when there&#8217;s a new major release of Xcode. At the time of writing the most recent version is 4.5.2, but inside the index there is at least one update restricted to only the preview release of Xcode 4.6).</p>
<p>The meat is in the downloadables array, so let&#8217;s look at one dict entry from it:</p>
<div class="codecolorer-container xml solarized-light" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:400px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dependencies<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;array</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>fileSize<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;integer<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>553669951<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/integer<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>identifier<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Xcode.SDK.iPhoneSimulator.5.0<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>name<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>iOS 5.0 Simulator<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>source<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>http://devimages.apple.com/downloads/xcode/simulators/ios_50_simulator-1.dmg<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>userInfo<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>ApplicationsBlockingInstallation<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;array<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>com.apple.iphonesimulator<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/array<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>IconType<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>IDEDownloadablesTypeSimulator<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>InstallPrefix<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>$(DEVELOPER)<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>InstalledIfAllPathsArePresent<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;array<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>$(DEVELOPER)/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/array<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>RequiresADCAuthentication<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;false</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Summary<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>This package enables testing of this previous version of iOS by installing legacy frameworks into the iOS Simulator. &nbsp;If your app intends to support this version of iOS, it is highly recommended that you download this package to aid in your development and debugging.<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Xcode.SDKs<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;array<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>CanonicalName<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>iphonesimulator5.0<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Path<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>$(DEVELOPER)/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Platform<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>com.apple.platform.iphonesimulator<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>SupportedDeviceFamilies<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;array<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;integer<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/integer<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;integer<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>2<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/integer<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/array<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Version<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>5.0<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/array<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>version<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>5.0.0.1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></div>
<p>Lots of useful, readable information here. We see the &#8216;displayed name&#8217; <code class="codecolorer text solarized-light"><span class="text">Name</span></code> key, the <code class="codecolorer text solarized-light"><span class="text">identifier</span></code> and <code class="codecolorer text solarized-light"><span class="text">version</span></code>, the .dmg download at <code class="codecolorer text solarized-light"><span class="text">source</span></code>, and some logic for how Xcode determines it&#8217;s installed via <code class="codecolorer text solarized-light"><span class="text">InstalledIfAllPathsArePresent</span></code>.</p>
<p>Notice the <code class="codecolorer text solarized-light"><span class="text">RequiresADCAuthentication</span></code> key, which is fairly new. Previously these legacy Simulator downloads were hosted at <code class="codecolorer text solarized-light"><span class="text">http://adcdownload.apple.com</span></code>, and would prompt you for an Apple ADC login. Currently there aren&#8217;t any downloads that require an ADC login, so Apple&#8217;s likely just reserving this behaviour for future use. It means it&#8217;s easier for us to actually grab the .dmg without needing an auth cookie set by our browser, which used to require a manual download of Xcode in order to have it set.</p>
<p>The other very important piece here is the <code class="codecolorer text solarized-light"><span class="text">InstallPrefix</span></code> key, set to <code class="codecolorer text solarized-light"><span class="text">$(DEVELOPER)</span></code>. We&#8217;re going to need this to actually install the .dmg correctly.</p>
<p>Once we&#8217;ve downloaded and mounted the installer .dmg, we can see it&#8217;s just a .pkg installer. The installer is a flat package, and we can use the <code class="codecolorer text solarized-light"><span class="text">pkgutil</span></code> to expand it to a working directory on our desktop and take a look:</p>
<div class="codecolorer-container text solarized-light codecolorer-noborder" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">pkgutil --expand /Volumes/MadRiver5M640.iPhoneSimulatorSDK5_0/iPhoneSimulatorSDK5_0.pkg ~/Desktop/simulator5</div></div>
<p>We&#8217;ve got the most basic flat package structure possible: a Bom, PackageInfo and Payload file. We can use the <code class="codecolorer text solarized-light"><span class="text">lsbom</span></code> command to get a list of all the payload items. If we take a look at the first few items, we see the top few items in a folder hierarchy:</p>
<div class="codecolorer-container text solarized-light codecolorer-noborder" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">. 41775 0/80<br />
./Platforms 40775 0/80<br />
./Platforms/iPhoneSimulator.platform 40775 0/80<br />
./Platforms/iPhoneSimulator.platform/Developer 40775 0/80<br />
./Platforms/iPhoneSimulator.platform/Developer/SDKs 40775 0/80<br />
./Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk 40775 0/80</div></div>
<p>Those &#8216;./&#8217;s at the beginning look like relative paths, don&#8217;t they? They are. If we&#8217;d install this package now using the <code class="codecolorer text solarized-light"><span class="text">installer</span></code> command and specify a root OS volume like <code class="codecolorer text solarized-light"><span class="text">/</span></code>, we&#8217;d wind up with this Platforms folder at ther root of our drive, which is not what we want. If we dig around inside the Xcode app bundle, we can find where the more current iOS Simulator is stored, at:</p>
<div class="codecolorer-container text solarized-light codecolorer-noborder" style="border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Applications/iPhone Simulator.app</div></div>
<p>This correlates with the <code class="codecolorer text solarized-light"><span class="text">InstallPrefix</span></code> key we saw earlier, telling us that we should effectively prefix this package&#8217;s target location with folder with <code class="codecolorer text solarized-light"><span class="text">/Applications/Xcode.app/Contents/Developer/</span></code>. To do this, we&#8217;ll edit the <code class="codecolorer text solarized-light"><span class="text">PackageInfo</span></code> file that contains metadata about the package. Specifically, we want to set the <code class="codecolorer text solarized-light"><span class="text">install-location</span></code> attribute in the <code class="codecolorer text solarized-light"><span class="text">pkg-info</span></code> element. See Stéphane Sudre&#8217;s excellent <a href="http://s.sudre.free.fr/Stuff/Ivanhoe/FLAT.html">Flat Package Format</a> page for more info on flat packages. With our small modification, the <code class="codecolorer text solarized-light"><span class="text">PackageInfo</span></code> should now look something like this:</p>
<div class="codecolorer-container xml solarized-light codecolorer-noborder" style="border:1px solid #9F9F9F;width:435px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;pkg-info</span> <span style="color: #000066;">install-location</span>=<span style="color: #ff0000;">&quot;/Applications/Xcode.app/Contents/Developer&quot;</span> <span style="color: #000066;">format-version</span>=<span style="color: #ff0000;">&quot;2&quot;</span> <span style="color: #000066;">relocatable</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000066;">deleteObsoleteLanguages</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000066;">identifier</span>=<span style="color: #ff0000;">&quot;com.apple.pkg.iPhoneSimulatorSDK5_0&quot;</span> <span style="color: #000066;">overwrite-permissions</span>=<span style="color: #ff0000;">&quot;no&quot;</span> <span style="color: #000066;">auth</span>=<span style="color: #ff0000;">&quot;admin&quot;</span> <span style="color: #000066;">postinstall-action</span>=<span style="color: #ff0000;">&quot;none&quot;</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;4.2.0.9000000000.1.1320101246&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span></div></div>
<p>Note the less-than-useful version number in the pkg itself. Now we can compile this back to a new flat package using the <code class="codecolorer text solarized-light"><span class="text">--flatten</span></code> option for <code class="codecolorer text solarized-light"><span class="text">pkgutil</span></code>:</p>
<div class="codecolorer-container text solarized-light codecolorer-noborder" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">pkgutil --flatten ~/Desktop/simulator5 ~/Desktop/iPhoneSimulatorSDK-5.0.0.1.pkg</div></div>
<p>The resulting file, <code class="codecolorer text solarized-light"><span class="text">iPhoneSimulatorSDK-5.0.0.1.pkg</span></code>, should now be installable as an addition to your Xcode installation.</p>
<p>Unfortunately, we&#8217;re still not done. If we skim through the index for this SDK&#8217;s identifier, we come across another entry, that contains a <code class="codecolorer text solarized-light"><span class="text">PatchFor</span></code> key:</p>
<div class="codecolorer-container xml solarized-light" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:400px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>dependencies<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;array</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>fileSize<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;integer<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>409313<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/integer<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>identifier<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Xcode.SDK.iPhoneSimulator.5.0<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>name<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>iOS 5.0 Simulator<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>source<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>http://devimages.apple.com/downloads/xcode/simulators/ios_50_simulator_patch1-3.dmg<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>userInfo<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>ApplicationsBlockingInstallation<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;array<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>com.apple.iphonesimulator<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/array<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>IconType<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>IDEDownloadablesTypeSimulator<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>InstallPrefix<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>$(DEVELOPER)<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>InstalledIfAllSHA1SumsMatch<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>$(DEVELOPER)/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk/System/Library/Frameworks/IOKit.framework/IOKit<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>29cc63b14597d18b0ee72700e749e2094a6127a7<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>$(DEVELOPER)/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk/usr/lib/libSystem.dylib<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>ebba4cd3fd4b2efbb735fd03cf884f10868afe30<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>$(DEVELOPER)/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk/usr/lib/libresolv.dylib<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>7ef21e0bf165992bf10a5ff4d51deb56d5a212e3<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>$(DEVELOPER)/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk/usr/lib/system/libSystem.override.dylib<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>2fded02920f04513f5882e96fa9f643f0051f815<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>$(DEVELOPER)/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk/usr/lib/system/libdispatch.dylib<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>e810fc59fde1dabcb29d3377717be2a0a2f4e9a5<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>$(DEVELOPER)/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk/usr/lib/system/libdispatch_debug.dylib<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>9f04c46b5bdbb2c84c13413f7733c4cc78659049<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>$(DEVELOPER)/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk/usr/lib/system/libdispatch_profile.dylib<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>60e92f01a6821298740a24e4b8275cfe5120b9bf<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>$(DEVELOPER)/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk/usr/lib/system/libxpc.dylib<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>4313a977a95b9eab68e896e9fec3b1691beb0e9b<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>$(DEVELOPER)/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk/usr/lib/system/libxpc_debug.dylib<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>3d6bf9d76a3996c8b0fa1bb46dfce1d2f50dde91<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>PatchFor<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;array<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Identifier<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Xcode.SDK.iPhoneSimulator.5.0<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Version<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>5.0.0.1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/array<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>RequiresADCAuthentication<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;false</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Summary<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>This package enables testing of this previous version of iOS by installing legacy frameworks into the iOS Simulator. &nbsp;If your app intends to support this version of iOS, it is highly recommended that you download this package to aid in your development and debugging.<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Xcode.SDKs<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;array<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>CanonicalName<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>iphonesimulator5.0<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Path<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>$(DEVELOPER)/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Platform<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>com.apple.platform.iphonesimulator<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>SupportedDeviceFamilies<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;array<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;integer<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/integer<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;integer<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>2<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/integer<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/array<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Version<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>5.0<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/array<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>version<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>5.0.1.1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/string<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></div>
<p>Again, the logic is clear. It&#8217;s a patch for version 5.0.0.1 of Xcode.SDK.iPhoneSimulator.5.0, and Xcode will know it&#8217;s installed according to the contents of the <code class="codecolorer text solarized-light"><span class="text">InstalledIfAllSHA1SumsMatch</span></code> key. In this case, it&#8217;s the SHA-1 hashes of a bunch of library files. If you inspect the BOM of this patch installer, you&#8217;ll see it&#8217;s only installing the same patched libraries given in this <code class="codecolorer text solarized-light"><span class="text">InstalledIfAllSHA1SumsMatch</span></code> dict. So, to install this you&#8217;ll need to perform the same modification to the <code class="codecolorer text solarized-light"><span class="text">PackageInfo</span></code> file to set the <code class="codecolorer text solarized-light"><span class="text">install-location</span></code> attribute.</p>
<p>It&#8217;s important to apply this patch, because if it is not applied, Xcode may detect that an installed component is not fully up to date, and prompt a dialog at launch, similar to when the MobileDevice support package is not installed or the correct version:</p>
<p><a href="http://macops.ca/wp-content/uploads/2012/11/xcode-legacy-simulator-update.png"><img class="alignnone size-full wp-image-132" title="xcode-legacy-simulator-update" src="http://macops.ca/wp-content/uploads/2012/11/xcode-legacy-simulator-update.png" alt="" width="916" height="635" /></a></p>
<p>A user can skip through this by failing the authorization prompt, but there&#8217;s otherwise no option to simply bypass the update.</p>
<p>With that, we should have everything we need to deploy a specific legacy iOS Simulator/SDK version. We know where to get the installers, what version they are, how Xcode knows whether they&#8217;re installed, and information for dependencies and patches that may see new uses in future versions. Your software distribution mechanism should be able to use all of this metadata to manage installations and updates for Xcode. If it doesn&#8217;t, you may need to supplement it with some of your own checking mechanisms.</p>
<p>This post&#8217;s specific use case of iOS Simulators may seem esoteric, but it&#8217;s a good example of the index metadata Xcode uses for its supplemental downloads, and a practical use of the <code class="codecolorer text solarized-light"><span class="text">pkgutil</span></code> command-line tool. With more and more packages being distributed in the flat package format, being familiar with using it to audit and modify packages is essential for administering OS X.</p>
]]></content:encoded>
			<wfw:commentRss>http://macops.ca/xcode-deployment-the-dvtdownloadableindex-and-ios-simulators/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Modifying the TCC database</title>
		<link>http://macops.ca/modifying-the-tcc-db/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=modifying-the-tcc-db</link>
		<comments>http://macops.ca/modifying-the-tcc-db/#comments</comments>
		<pubDate>Sat, 10 Nov 2012 13:27:33 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Mountain Lion]]></category>
		<category><![CDATA[preferences]]></category>
		<category><![CDATA[privacy]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[SQLite3]]></category>
		<category><![CDATA[TCC]]></category>

		<guid isPermaLink="false">http://macops.synthist.net/?p=1</guid>
		<description><![CDATA[Mountain Lion introduced a new iOS-like feature to allow users to be notified when an application requests access to that user&#8217;s contacts: …and to be able to modify this access later: Why does Final Cut Pro 7 want to access contacts? Final Cut Pro 7 introduced a feature that uses iChat (which doesn&#8217;t even really [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://macops.ca/wp-content/uploads/2012/11/kTCCServiceAddressBook.png"><img class="size-full wp-image-12 alignleft" title="kTCCServiceAddressBook" src="http://macops.ca/wp-content/uploads/2012/11/kTCCServiceAddressBook.png" alt="" width="64" height="64" /></a></p>
<p>Mountain Lion introduced a new iOS-like feature to allow users to be notified when an application requests access to that user&#8217;s contacts:</p>
<p><img class="alignnone" title="TCC dialog" src="http://macops.ca/wp-content/uploads/2012/11/tcc-fcp-dialog.png" alt="" /></p>
<p>…and to be able to modify this access later:</p>
<p><img class="alignnone" title="TCC dialog" src="http://macops.ca/wp-content/uploads/2012/11/tcc-prefpane.png" alt="" /></p>
<p>Why does Final Cut Pro 7 want to access contacts? Final Cut Pro 7 introduced a feature that uses iChat (which doesn&#8217;t even really <em>exist</em> in Mountain Lion), therefore when a user first launches FCP, OS X will ask permission to allow FCP to access that user&#8217;s contacts.</p>
<p>It might be nice to be able to pre-allow or -disallow access for applications without user intervention, especially in scenarios where user Library data isn&#8217;t persistent across logins in a multi-user environment, where users would otherwise be nagged frequently to access what&#8217;s likely an empty Contacts database.</p>
<p><span id="more-1"></span></p>
<p>These contacts turn out to be stored in an SQLite3 database, located in the user&#8217;s library folder:</p>
<p><code class="codecolorer text solarized-light"><span class="text">~/Library/Application Support/com.apple.TCC/TCC.db</span></code></p>
<p>This database is managed by the <code class="codecolorer text solarized-light"><span class="text">tccd</span></code> daemon located at:</p>
<p><code class="codecolorer text solarized-light"><span class="text">/System/Library/PrivateFrameworks/TCC.framework/Resources/tccd</span></code></p>
<p>We can query it with the built-in <code class="codecolorer text solarized-light"><span class="text">sqlite3</span></code> command-line tool:</p>
<div class="codecolorer-container text solarized-light" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">➜ sqlite3 ~/Library/Application\ Support/com.apple.TCC/TCC.db<br />
<br />
SQLite version 3.7.12 2012-04-03 19:43:07<br />
Enter &quot;.help&quot; for instructions<br />
Enter SQL statements terminated with a &quot;;&quot;<br />
<br />
sqlite&gt; .tables<br />
access access_overrides access_times admin</div></div>
<p>There&#8217;s some useful information in the <code class="codecolorer text solarized-light"><span class="text">access</span></code> table:</p>
<div class="codecolorer-container sql solarized-light" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="sql codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">sqlite<span style="color: #66cc66;">&gt;</span> <span style="color: #66cc66;">.</span>dump access<br />
PRAGMA foreign_keys<span style="color: #66cc66;">=</span>OFF;<br />
<span style="color: #993333; font-weight: bold;">BEGIN</span> <span style="color: #993333; font-weight: bold;">TRANSACTION</span>;<br />
<span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> access <span style="color: #66cc66;">&#40;</span>service TEXT <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span> client TEXT <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span> client_type <span style="color: #993333; font-weight: bold;">INTEGER</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span> allowed <span style="color: #993333; font-weight: bold;">INTEGER</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span> prompt_count <span style="color: #993333; font-weight: bold;">INTEGER</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span> <span style="color: #993333; font-weight: bold;">CONSTRAINT</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #66cc66;">&#40;</span>service<span style="color: #66cc66;">,</span> client<span style="color: #66cc66;">,</span> client_type<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> <span style="color: #ff0000;">&quot;access&quot;</span> <span style="color: #993333; font-weight: bold;">VALUES</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'kTCCServiceAddressBook'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'com.apple.FinalCutPro'</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> <span style="color: #ff0000;">&quot;access&quot;</span> <span style="color: #993333; font-weight: bold;">VALUES</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'kTCCServiceAddressBook'</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">'com.google.Chrome'</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span>;<br />
COMMIT;</div></div>
<p>Here we&#8217;ve got FCP and Google Chrome (the latter triggered because we visited GMail). The last three integer columns store the values for <code class="codecolorer text solarized-light"><span class="text">client_type</span></code>, <code class="codecolorer text solarized-light"><span class="text">allowed</span></code>, and <code class="codecolorer text solarized-light"><span class="text">prompt_count</span></code>.</p>
<p>Given this very simple database schema, it&#8217;s pretty trivial to update this database ourselves directly. In my experience, when the database gets updated, the Security &amp; Privacy preferences pane responds to the change as soon as its window again receives focus.</p>
<p>I wrote a Python script that allows for ad-hoc changes to the <code class="codecolorer text solarized-light"><span class="text">allowed</span></code> column, given an app bundle id. It should also be usable in scenarios where a user may be brand new and not yet had the TCC database created, so it will handle the initial schema creation of the database if it doesn&#8217;t already exist.</p>
<p>This is available <a href="https://github.com/timsutton/scripts/blob/master/tccmanager/tccmanager.py">here</a>. It currently assumes you&#8217;ll be running the script as the user whose database will be modified.</p>
]]></content:encoded>
			<wfw:commentRss>http://macops.ca/modifying-the-tcc-db/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Disabling updates in Acrobat Pro X: A case study in wasted effort</title>
		<link>http://macops.ca/disabling-updates-in-acrobat-pro-x/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=disabling-updates-in-acrobat-pro-x</link>
		<comments>http://macops.ca/disabling-updates-in-acrobat-pro-x/#comments</comments>
		<pubDate>Sun, 26 Aug 2012 15:32:59 +0000</pubDate>
		<dc:creator>tim</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Acrobat]]></category>
		<category><![CDATA[Adobe]]></category>
		<category><![CDATA[Disabling update checks]]></category>
		<category><![CDATA[preferences]]></category>

		<guid isPermaLink="false">http://macops.ca/?p=53</guid>
		<description><![CDATA[Adobe&#8217;s Acrobat family of products has been historically painful for IT to distribute and manage. While this article focuses on a simple management setting – suppressing update checks and notifications for all users – it&#8217;s an example of how configuring even the simplest, arguably most universally required management setting for an Acrobat-deploying IT department is [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://macops.ca/wp-content/uploads/2012/11/aprox-updater_128x128.png"><img src="http://macops.ca/wp-content/uploads/2012/11/aprox-updater_128x128.png" alt="" title="aprox-updater_128x128" width="128" height="128" class="alignleft size-full wp-image-92" /></a>Adobe&#8217;s Acrobat family of products has been historically painful for IT to distribute and manage. While this article focuses on a simple management setting – suppressing update checks and notifications for all users – it&#8217;s an example of how configuring even the simplest, arguably most universally required management setting for an Acrobat-deploying IT department is an exercise in frustration at every turn, largely due to Adobe&#8217;s Acrobat team insisting on reinventing the wheel for basic functionality already provided by native OS APIs and frameworks, compounded by many technical errors in their documentation.</p>
<p>On OS X, Acrobat Pro X and Reader 10 became distributable in the standard Apple pkg format, and this was generally a huge improvement for the deployment and update process. Acrobat Pro 9 currently requires <em>twenty</em> sequential patches required to bring Acrobat Pro 9 to an up-to-date version.</p>
<div id="attachment_29" class="wp-caption alignnone" style="width: 562px"><a href="http://macops.ca/wp-content/uploads/2012/11/acropro9-20updates.png"><img class="size-full wp-image-29" title="acropro9-20updates" src="http://macops.ca/wp-content/uploads/2012/11/acropro9-20updates.png" alt="" width="552" height="621" /></a><p class="wp-caption-text">Too many updates.</p></div>
<p>Things are much better now, but configuring a common setting such as disabling update checks for all users has remained unnecessarily complicated, for despite Adobe using a property list to store these parameters, they were per-user only, requiring these to be managed either using MCX/Profiles or a manual script to apply the appropriate preference in every user&#8217;s Library folder (ie. at login time with a LaunchAgent).<span id="more-53"></span>Adobe has alluded to built-in functionality for disabling updates in Pro X in the past, so we&#8217;ll summarize what&#8217;s been presented to date:</p>
<p><strong>Adobe Provisioning Tool</strong></p>
<p>The <a href="http://ftp.adobe.com/pub/adobe/acrobat/mac/10.x/10.0.0/misc">Adobe Provisioning Tool</a> would have you believe, going by its usage statement, that there is a <code class="codecolorer text solarized-light"><span class="text">-M</span></code> option to suppress updates. There is no such functionality anywhere in the <code class="codecolorer text solarized-light"><span class="text">adobe_prtk</span></code> binary on OS X.</p>
<p><strong>FeatureLockDown file</strong></p>
<p>The <a href="http://www.adobe.com/content/dam/Adobe/en/devnet/creativesuite/pdfs/AAMEE_Exception/en_us/AAMEE_Exceptions.pdf">AAMEE Technical Note</a> on &#8220;Installing and Configuring Exception Payloads&#8221; suggests you can configure the FeatureLockdown system. It says to just modify a file inside the Acrobat Pro X .app bundle at <code class="codecolorer text solarized-light"><span class="text">Contents/MacOS/Preferences/FeatureLockDown</span></code> and change this 822-character line:</p>
<div class="codecolorer-container text solarized-light codecolorer-noborder" style="border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;&lt; /DefaultLaunchAttachmentPerms [ /c &lt;&lt; /BuiltInPermList [ /t ()version:1|.ade:3|.adp:3|.app:3|.arc:3|.arj:3|.asp:3|.bas:3|.bat:3|.bz:3|.bz2:3|.cab:3|.chm:3|.class:3|.cmd:3|.com:3|.command:3|.cpl:3|.crt:3|.csh:3|.desktop:3|.dll:3|.exe:3|.fxp:3|.gz:3|.hex:3|.hlp:3|.hqx:3|.hta:3|.inf:3|.ini:3|.ins:3|.isp:3|.its:3|.jar:3|.job:3|.js:3|.jse:3|.ksh:3|.lnk:3|.lzh:3|.mad:3|.maf:3|.mag:3|.mam:3|.maq:3|.mar:3|.mas:3|.mat:3|.mau:3|.mav:3|.maw:3|.mda:3|.mdb:3|.mde:3|.mdt:3|.mdw:3|.mdz:3|.msc:3|.msi:3|.msp:3|.mst:3|.ocx:3|.ops:3|.pcd:3|.pi:3|.pif:3|.pkg:3|.prf:3|.prg:3|.pst:3|.rar:3|.reg:3|.scf:3|.scr:3|.sct:3|.sea:3|.shb:3|.shs:3|.sit:3|.tar:3|.taz:3|.tgz:3|.tmp:3|.url:3|.vb:3|.vbe:3|.vbs:3|.vsmacros:3|.vss:3|.vst:3|.vsw:3|.webloc:3|.ws:3|.wsc:3|.wsf:3|.wsh:3|.z:3|.zip:3|.zlo:3|.zoo:3|.term:3|.tool:3|.pdf:2|.fdf:2) ] &gt;&gt; ]</div></div>
<p>to this 843-character line:</p>
<div class="codecolorer-container text solarized-light codecolorer-noborder" style="border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;&lt; /Updater [ /b false ] /DefaultLaunchAttachmentPerms [ /c &lt;&lt; /BuiltInPermList [ /t (version:1|.ade:3|.adp:3|.app:3|.arc:3|.arj:3|.asp:3|.bas:3|.bat:3|.bz:3|.bz2:3|.cab:3|.chm:3|.class:3|.cmd:3|.com:3|.command:3|.cpl:3|.crt:3|.csh:3|.desktop:3|.dll:3|.exe:3|.fxp:3|.gz:3|.hex:3|.hlp:3|.hqx:3|.hta:3|.inf:3|.ini:3|.ins:3|.isp:3|.its:3|.jar:3|.job:3|.js:3|.jse:3|.ksh:3|.lnk:3|.lzh:3|.mad:3|.maf:3|.mag:3|.mam:3|.maq:3|.mar:3|.mas:3|.mat:3|.mau:3|.mav:3|.maw:3|.mda:3|.mdb:3|.mde:3|.mdt:3|.mdw:3|.mdz:3|.msc:3|.msi:3|.msp:3|.mst:3|.ocx:3|.ops:3|.pcd:3|.pi:3|.pif:3|.pkg:3|.prf:3|.prg:3|.pst:3|.rar:3|.reg:3|.scf:3|.scr:3|.sct:3|.sea:3|.shb:3|.shs:3|.sit:3|.tar:3|.taz:3|.tgz:3|.tmp:3|.url:3|.vb:3|.vbe:3|.vbs:3|.vsmacros:3|.vss:3|.vst:3|.vsw:3|.webloc:3|.ws:3|.wsc:3|.wsf:3|.wsh:3|.z:3|.zip:3|.zlo:3|.zoo:3|.term:3|.tool:3|.pdf:2|.fdf:2) ] &gt;&gt; ]</div></div>
<p>I did not find this method to work reliably.</p>
<p>You might also come across the topic of updates in the <a href="http://helpx.adobe.com/content/dam/kb/en/837/cpsid_83709/attachments/Acrobat_Enterprise_Administration.pdf">Enterprise Administration Guide for Acrobat</a>, and see a few options there (Section 15.6, page 139). We&#8217;ll examine these in reverse order, because up until recently this would have been my order of preference (given that the first option was broken until very recently.)</p>
<p><strong>Option 15.6.3: Remove the Updater plugin itself</strong></p>
<p>This option is looking pretty good at this point, which is to remove the Updater plugin entirely to prevent it from checking for updates. However, we would need to make a point of doing this every time we run an updater pkg for Acrobat.</p>
<p>It&#8217;s clear that we&#8217;ve reached a less read-over section of the guide, as there are ambiguous terms and incorrect filenames/paths in nearly <em>every written line</em> of this section. Because Adobe so rarely follows system conventions in these implementations, I didn&#8217;t feel like could easily gloss over an error and assume the writer meant to write something else.</p>
<p><strong>Option 15.6.2: Set the update mode to manual</strong></p>
<p>&#8220;The update mode is set on a per user basis as follows: (…)&#8221;</p>
<p>We can skip this – this is what we&#8217;re already having to do, set per-user preferences with MCX, a Profile or script. In this case, we <em>can</em> assume the writer meant to use the correct path to the plist file, and not one that doesn&#8217;t normally exist on an OS X system.</p>
<p><strong>Option 15.6.1: Disabling and locking the Updater</strong></p>
<p>This sounds familiar to that FeatureLockdown no-line-break mess we&#8217;re still trying to forget we were ever desperate enough to try in the first place. And in fact, it does seem to be using the same FeatureLockDown subsystem to disable the plugin, except it&#8217;s writing the <code class="codecolorer text solarized-light"><span class="text">bUpdater</span></code> boolean value in a plist. The documentation doesn&#8217;t say at all <em>where</em> this plist is, but we can take a good guess.</p>
<p>The obvious one to try is the system default preferences folder at <code class="codecolorer text solarized-light"><span class="text">/Library/Preferences</span></code>. We can use these plist contents for both Acrobat Pro X and Reader, using the plist names <code class="codecolorer text solarized-light"><span class="text">com.adobe.Acrobat.Pro.plist</span></code> and <code class="codecolorer text solarized-light"><span class="text">com.adobe.Reader.plist</span></code>, respectively:</p>
<div class="codecolorer-container xml solarized-light" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;UTF-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span><br />
<span style="color: #00bbdd;">&lt;!DOCTYPE plist PUBLIC &quot;-//Apple//DTD PLIST 1.0//EN&quot; &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&gt;</span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;plist</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>10<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>FeatureLockdown<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>bUpdater<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;false</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; &nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dict<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/plist<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></div>
<p>It&#8217;s documented to work as of 10.1.1, but it only works as of version 10.1.4 of Acrobat and Reader. Adobe was <a href="http://forums.adobe.com/message/4640192">pretty responsive</a> in fixing the broken functionality once it was reported.</p>
<p>So now, the answer is pretty simple. Push a simple-enough plist to a system location or manage the preference as you would most others that work with the defaults system. I went through the previous options just as a demonstration of how Adobe manages to, in duplicating their own efforts in software implementations, effectively duplicate efforts by many orders of magnitude across IT organizations worldwide, who simply need to deploy a common application without resorting to scripted hacks and workarounds to manage very trivial behaviour.</p>
<p>It&#8217;s great that Acrobat Pro X and Reader are getting easier to deploy and configure on OS X, but it&#8217;s been a <a href="http://code.google.com/p/munki/source/browse/code/client/munkilib/adobeutils.py#823">long road</a> getting there.</p>
]]></content:encoded>
			<wfw:commentRss>http://macops.ca/disabling-updates-in-acrobat-pro-x/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
