/core/externals/update-engine/Samples/HelloEngine/README.html

http://macfuse.googlecode.com/ · HTML · 256 lines · 188 code · 68 blank · 0 comment · 0 complexity · 4a4721f4d109d70b2a5cb2775f62d96e MD5 · raw file

  1. <html>
  2. <head>
  3. <title>Welcome to HelloEngine</title>
  4. </head>
  5. <body bgcolor="white">
  6. <h1>Welcome to HelloEngine</h1>
  7. Welcome to HelloEngine, a minimal, but functional, Update Engine
  8. program. <tt>HelloEngine.m</tt> has some comments about how Update
  9. Engine works. This file has instructions on how to run the sample,
  10. and to get your own Stuff into Update Engine's pipeline.
  11. <p>
  12. Here's how to run things:
  13. <ul>
  14. <li> Copy <tt>Samples/HelloEngine/TestApp.dmg</tt> to <tt>/tmp</tt>
  15. <li> Copy <tt>Samples/HelloEngine/ServerResponse.plist</tt> to <tt>/tmp</tt>
  16. <li> Build HelloEngine
  17. <li> Run HelloEngine:<br>
  18. <pre>HelloEngine -productID com.google.HelloEngineTest -version 1.2 -serverURL file:///tmp/ServerResponse.plist</pre>
  19. <li> Note new file, <tt>/tmp/HiEngine.sh</tt>, which has been "updated".
  20. Run that for a little message of greetings.
  21. <pre>
  22. </pre>
  23. </ul>
  24. <p>
  25. You'll see a lot of output. This is Update Engine letting you know
  26. what's going on, and can be useful when debugging things. It also
  27. looks cool.
  28. <p>
  29. The very last line of the output will look something like:
  30. <pre>
  31. 2008-09-12 11:51:01.933 HelloEngine[7055/0x0b0e] [lvl=2] main Update Succeeded
  32. </pre>
  33. <p>
  34. The last word from HelloEngine will be "Succeeded" or "Failed". If it
  35. Succeeded, try running <tt>/tmp/HiEngine.sh</tt>
  36. <h1>Getting HelloEngine to run your own stuff</h1>
  37. There are a couple of steps to get HelloEngine to run your stuff:
  38. <ul>
  39. <li> Edit the <tt>.engine_install</tt> script
  40. <li> Build your disk image
  41. <li> Calculate hash and file size
  42. <li> Edit your <tt>ServerResponse.plist</tt>
  43. </ul>
  44. <h2>.engine_install</h2>
  45. First you'll need to edit the install script, which you can find at
  46. <tt>Samples/HelloEngine/TestAppDMGSource/.engine_install</tt>. This script
  47. is what does the heavy lifting of updating your product.
  48. <p>
  49. <tt>.engine_install</tt> is required for Update Engine to function
  50. properly. You can also create <tt>.engine_preinstall</tt> and
  51. <tt>.engine_postinstall</tt> scripts to do preflight and postflight
  52. work. Outside of these scripts, Update Engine doesn't care what you
  53. have on the disk image.
  54. <p>
  55. The standard-out of the preinstall script gets added to the
  56. environment of the install and postinstall scripts under the
  57. environment variable <tt>KS_PREINSTALL_OUT</tt>. Likewise, the
  58. standard-out of the install script gets added to the environment of
  59. the postinstall script under the environment variable
  60. <tt>KS_INSTALL_OUT</tt>. This way you can pass information from one
  61. script phase to the next.
  62. <p>
  63. The scripts can be written in any language you want, but you'll want to
  64. stick to the languages (and language versions) that exist on your
  65. user's machines - they probably don't want to download and install the
  66. Object Fortran++ Scripting Bridge so that you can update your
  67. software. Likewise, if you're using Python, don't use any Python 2.5
  68. features if you intend to update users on Tiger, who only have python 2.3.
  69. <p>
  70. <tt>.engine_install</tt> and the others don't even have to be a
  71. script, they can be compiled C programs if that makes sense for what
  72. you need to do.
  73. <p>
  74. The first argument of the script is the directory to the mount point
  75. of the disk image that Update Engine downloads. Be aware that this
  76. path can contain spaces, so do whatever string-space-quoting hygiene
  77. is necessary for your language of choice.
  78. <p>
  79. Inside of the script, you're welcome to do whatever you want, assuming
  80. it can be done as the user ID that the HelloEngine tool is run as. If
  81. you run it as root, then you can do most anything, please don't delete
  82. the user's <tt>/Application</tt> directory.
  83. <h2>Build your Disk Image</h2>
  84. Once you've written your script, you'll need to build your disk image.
  85. The easy way to do this is to drop all your stuff into a directory and
  86. use Disk Utility to create the disk image. The command to do so is
  87. hidden under <i>File &gt; New &gt; New Disk Image From Folder</i>.
  88. Choose the <tt>TestAppDMGSource</tt> folder, or whatever folder you're using for
  89. your product update, and make sure you're making a compressed,
  90. unencrypted disk image.
  91. <p>
  92. Here's a command for doing the same thing that's easier to put into an
  93. Xcode project:
  94. <pre>
  95. hdiutil create -ov -imagekey zlib-level=9 -fs HFS+ -format UDZO -scrub
  96. -srcfolder $DIR $DISKIMAGENAME
  97. </pre>
  98. <p>
  99. In a real-world application, this can (and should) be the disk image
  100. that you give your users. This saves you from having to build, test,
  101. and deploy two different payloads for your product. The reason
  102. the scripts have the leading dot is so that they won't interfere with
  103. the Finder's presentation of the disk image when it's mounted by the user.
  104. <h2>Caculate Hash and File Size</h2>
  105. Once you have the disk image, you'll need to calculate a checksum, and
  106. put the checksum and size into the <tt>ServerResponse.plist</tt> file.
  107. <p>
  108. First, calculate the checksum:
  109. <pre>
  110. $ openssl sha1 -binary TestApp.dmg | openssl base64
  111. </pre>
  112. This will output something like
  113. <pre>
  114. BnKj+Bpy4KspQ4qzlkRn6EIaJ4g=
  115. </pre>
  116. After you figure out how to pronounce that, you'll need to figure out
  117. how big the file is:
  118. <pre>
  119. $ ls -l TestApp.dmg
  120. -rw-r--r-- 1 bork bork 50405 Sep 11 18:29 TestApp.dmg
  121. </pre
  122. So it's 50405 bytes.
  123. <h2>Edit your ServerResponse.plist</h2>
  124. Edit the ServerResponse.plist and plug the values into the Size and
  125. Hash settings:
  126. <pre>
  127. <font color="gray">
  128. ...
  129. &lt;array&gt;
  130. &lt;dict&gt;
  131. &lt;key&gt;ProductID&lt;/key&gt;
  132. &lt;string&gt;com.google.HelloEngineTest&lt;/string&gt;
  133. &lt;key&gt;Predicate&lt;/key&gt;
  134. &lt;string&gt;Ticket.version != '2.0'&lt;/string&gt;
  135. &lt;key&gt;Codebase&lt;/key&gt;
  136. &lt;string&gt;file:///tmp/TestApp.dmg&lt;/string&gt;
  137. <font color="black">
  138. &lt;key&gt;Size&lt;/key&gt;
  139. &lt;string&gt;<b>50405</b>&lt;/string&gt;
  140. &lt;key&gt;Hash&lt;/key&gt;
  141. &lt;string&gt;<b>BnKj+Bpy4KspQ4qzlkRn6EIaJ4g=</b>&lt;/string&gt;
  142. </font>
  143. &lt;/dict&gt;
  144. &lt;/array&gt;
  145. ...
  146. </font>
  147. </pre>
  148. In a real development environment, you'll probably want an Xcode
  149. script build phase to do this automatically for you.
  150. <p>
  151. Now you can use your <tt>ServerResponse.plist</tt> and your
  152. <tt>TestApp.dmg</tt> with HelloEngine to get your stuff run.
  153. <h1>What can go wrong</h1>
  154. There are some moving pieces involved, and some things that might go wrong
  155. as you get things working. Here are some common ones:
  156. <ul>
  157. <li> Forgot to replace <tt>/tmp/TestApp.dmg</tt>
  158. <li> Forgot to copy <tt>ServerResponse.plist</tt> to <tt>/tmp</tt>
  159. <li> Bad hash or bad size when you change the payload<br>
  160. </ul>
  161. These result in <tt>ServerResponse.plist</tt> having a size and/or hash that's
  162. out of sync with the TestApp.dmg file. Update Engine will reject any paylod
  163. that doesn't match the size and hash.
  164. <ul>
  165. <li> Your <tt>.engine_install</tt> is not <tt>+x</tt>
  166. </ul>
  167. Make sure that your .engine_install file has the executable bit, set with
  168. <tt>chmod +x .engine_install</tt>
  169. <ul>
  170. <li> Making assumptions about the current working directory
  171. </ul>
  172. The current working directory for your script is undefined, and will
  173. probably be the directory where you are running the HelloEngine
  174. command from. This can confuse your testing if you run HelloEngine
  175. with your current working directory being that of your
  176. TestAppDMGSource directory. The script will work fine when you run
  177. the install script by hand, but will fail when Update Engine is doing
  178. its thing.
  179. <p>
  180. Make sure you get the path to your mounted disk from the
  181. first argument to the script, and make sure that you account for the
  182. the fact that it might contain spaces. Even if your disk image name
  183. doesn't contain spaces, the system might mount it at
  184. <tt>"/Volumes/Payload 1"</tt> if <tt>/Volumes/Payload</tt> is already
  185. in use.
  186. </ul>
  187. </body>
  188. </html>