- isolate all the sudo stuff in %clean
[bootmanager.git] / documentation / booting-nodes.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
3 "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
4 <article>
5   <articleinfo>
6     <title>Booting PlanetLab Nodes</title>
7
8     <author>
9       <firstname>Aaron</firstname>
10
11       <surname>Klingaman</surname>
12
13       <email>alk@absarokasoft.com</email>
14     </author>
15
16     <affiliation>
17       <orgname>Princeton University</orgname>
18     </affiliation>
19
20     <revhistory>
21       <revision>
22         <revnumber>1.0</revnumber>
23
24         <date>March 16, 2006</date>
25
26         <authorinitials>AK</authorinitials>
27
28         <revdescription>
29           <para>Initial draft of new PDN, based on existing BootManager and
30           BootCD Technical documentation</para>
31         </revdescription>
32       </revision>
33     </revhistory>
34   </articleinfo>
35
36   <section>
37     <title>Overview</title>
38
39     <para>This document describes a reference implementation for securely
40     booting PlanetLab nodes, that has been collectively named the
41     BootManager.</para>
42   </section>
43
44   <section>
45     <title>Components</title>
46
47     <para>The entire Boot Manager system consists of several components that
48     are designed to work together to provide the ability to install, validate,
49     and boot a PlanetLab node. These components are:</para>
50
51     <itemizedlist>
52       <listitem>
53         <para>The existing, stardard MA provided calls to allow principals to
54         add and manage node records</para>
55       </listitem>
56
57       <listitem>
58         <para>New principal used API calls to create and download
59         node-specific configuration files</para>
60       </listitem>
61
62       <listitem>
63         <para>A new set of API calls and a new authentication mechanism to be
64         used by the nodes</para>
65       </listitem>
66
67       <listitem>
68         <para>A code package to be run in the boot cd environment on nodes
69         containing core install/validate/boot logic</para>
70       </listitem>
71     </itemizedlist>
72   </section>
73
74   <section>
75     <title>Soure Code</title>
76
77     <para>All BootManager source code is located in the repository
78     'bootmanager' on the PlanetLab CVS system. For information on how to
79     access CVS, consult the PlanetLab website. Unless otherwise noted, all
80     file references refer to this repository.</para>
81   </section>
82
83   <section>
84     <title>Stardard MA Interfaces</title>
85
86     <para>The API calls provided by the Management Authority are called out
87     here for their relevency, and to document any extentions to them. See the
88     PlanetLab Core Specification for more details.</para>
89
90     <para><itemizedlist>
91         <listitem>
92           <para>AddNode( authentication, node_values )</para>
93
94           <para>Add a new node record</para>
95         </listitem>
96
97         <listitem>
98           <para>UpdateNode( authentication, update_values )</para>
99
100           <para>Update an existing node record</para>
101         </listitem>
102
103         <listitem>
104           <para>DeleteNode( authentication, node_id )</para>
105
106           <para>Removes a node from the MA list of nodes</para>
107         </listitem>
108       </itemizedlist></para>
109
110     <para>Additional node-specific values have been added to the AddNode and
111     UpdateNode calls:</para>
112
113     <itemizedlist>
114       <listitem>
115         <para>boot_state</para>
116
117         <para>Store what state the node is currently in.</para>
118       </listitem>
119     </itemizedlist>
120
121     <section>
122       <title>Boot States</title>
123
124       <para>Each node always has one of four possible boot states.</para>
125
126       <orderedlist>
127         <listitem>
128           <para>'inst'</para>
129
130           <para>Install. The boot state cooresponds to a new node that has not
131           yet been installed, but record of it does exist. When the boot
132           manager starts, and the node is in this state, the user is prompted
133           to continue with the installation. The intention here is to prevent
134           a non-PlanetLab machine (like a user's desktop machine) from
135           becoming inadvertantly wiped and installed with the PlanetLab node
136           software.</para>
137         </listitem>
138
139         <listitem>
140           <para>'rins'</para>
141
142           <para>Reinstall. In this state, a node will reinstall the node
143           software, erasing anything that might have been on the disk
144           before.</para>
145         </listitem>
146
147         <listitem>
148           <para>'boot'</para>
149
150           <para>Boot. This state cooresponds with nodes that have sucessfully
151           installed, and can be chain booted to the runtime node
152           kernel.</para>
153         </listitem>
154
155         <listitem>
156           <para>'dbg'</para>
157
158           <para>Debug. Regardless of whether or not a machine has been
159           installed, this state sets up a node to be debugged by
160           administrators.</para>
161         </listitem>
162       </orderedlist>
163     </section>
164   </section>
165
166   <section>
167     <title>Additional Principal Based MA Interfaces</title>
168
169     <para>The following API calls have been added to the MA:</para>
170
171     <para><itemizedlist>
172         <listitem>
173           <para>GenerateNodeConfigurationFile( authentication, node_id
174           )</para>
175
176           <para>Return a configuration file containing node details, including
177           network settings, the node_id, and a key to be used for
178           authenticated node calls.</para>
179         </listitem>
180       </itemizedlist></para>
181   </section>
182
183   <section>
184     <title>Additional Node Based Interfaces and Authentication</title>
185
186     <section>
187       <title>Authentication</title>
188
189       <para>The API calls described below will be run by the nodes themselves,
190       so a new authentication mechanism is required. As is done with other PLC
191       API calls, the first parameter to all BootManager related calls will be
192       an authentication structure, consisting of these named fields:</para>
193
194       <itemizedlist>
195         <listitem>
196           <para>AuthMethod</para>
197
198           <para>The authentication method, only 'hmac' is currently
199           supported</para>
200         </listitem>
201
202         <listitem>
203           <para>node_id</para>
204
205           <para>The node id, contained on the configuration file.</para>
206         </listitem>
207
208         <listitem>
209           <para>node_ip</para>
210
211           <para>The node's primary IP address. This will be checked with the
212           node_id against PLC records.</para>
213         </listitem>
214
215         <listitem>
216           <para>value</para>
217
218           <para>The authentication string, depending on method. For the 'hmac'
219           method, a hash for the call using the HMAC algorithm, made from the
220           parameters of the call the key contained on the configuration file.
221           For specifics on how this is created, see below.</para>
222         </listitem>
223       </itemizedlist>
224
225       <para>Authentication is succesful if PLC is able to create the same hash
226       from the values usings its own copy of the node key. If the hash values
227       to not match, then either the keys do not match or the values of the
228       call were modified in transmision and the node cannot be
229       authenticated.</para>
230
231       <para>Both the BootManager and the authentication software at PLC must
232       agree on a method for creating the hash values for each call. This hash
233       is essentially a finger print of the method call, and is created by this
234       algorithm:</para>
235
236       <orderedlist>
237         <listitem>
238           <para>Take the value of every part of each parameter, except the
239           authentication structure, and convert them to strings. For arrays,
240           each element is used. For dictionaries, not only is the value of all
241           the items used, but the keys themselves. Embedded types (arrays or
242           dictionaries inside arrays or dictionaries, etc), also have all
243           values extracted.</para>
244         </listitem>
245
246         <listitem>
247           <para>Alphabetically sort all the parameters.</para>
248         </listitem>
249
250         <listitem>
251           <para>Concatenate them into a single string.</para>
252         </listitem>
253
254         <listitem>
255           <para>Prepend the string with the method name and [, and append
256           ].</para>
257         </listitem>
258       </orderedlist>
259
260       <para>The implementation of this algorithm is in the function
261       serialize_params in the file source/BootAPI.py. The same algorithm is
262       located in the 'plc_api' repository, in the function serialize_params in
263       the file PLC/Auth.py.</para>
264
265       <para>The resultant string is fed into the HMAC algorithm with the node
266       key, and the resultant hash value is used in the authentication
267       structure.</para>
268
269       <para>This authentication method makes a number of assumptions, detailed
270       below.</para>
271
272       <orderedlist>
273         <listitem>
274           <para>All calls made to PLC are done over SSL, so the details of the
275           authentication structure cannot be viewed by 3rd parties. If, in the
276           future, non-SSL based calls are desired, a sequence number or some
277           other value making each call unique will would be required to
278           prevent replay attacks. In fact, the current use of SSL negates the
279           need to create and send hashes across - technically, the key itself
280           could be sent directly to PLC, assuming the connection is made to an
281           HTTPS server with a third party signed SSL certificate.</para>
282         </listitem>
283
284         <listitem>
285           <para>Athough calls are done over SSL, they use the Python class
286           libary xmlrpclib, which does not do SSL certificate
287           verification.</para>
288         </listitem>
289       </orderedlist>
290     </section>
291
292     <section>
293       <title>Additional API Calls</title>
294
295       <para>The following calls have been added:</para>
296
297       <itemizedlist>
298         <listitem>
299           <para>BootUpdateNode( authentication, update_values )</para>
300
301           <para>Update a node record, including its boot state, primary
302           network, or ssh host key.</para>
303         </listitem>
304
305         <listitem>
306           <para>BootCheckAuthentication( authentication )</para>
307
308           <para>Simply check to see if the node is recognized by the system
309           and is authorized.</para>
310         </listitem>
311
312         <listitem>
313           <para>BootGetNodeDetails( authentication )</para>
314
315           <para>Return details about a node, including its state, what
316           networks the PLC database has configured for the node, and what the
317           model of the node is.</para>
318         </listitem>
319
320         <listitem>
321           <para>BootNotifyOwners( authentication, message, include_pi,
322           include_tech, include_support )</para>
323
324           <para>Notify someone about an event that happened on the machine,
325           and optionally include the site PIs, technical contacts, and
326           PlanetLab Support.</para>
327         </listitem>
328       </itemizedlist>
329     </section>
330   </section>
331
332   <section>
333     <title>Core Package</title>
334
335     <para>The Boot Manager core package, which is run on the nodes and
336     contacts the Boot API as necessary, is responsible for the following major
337     functional units:</para>
338
339     <itemizedlist>
340       <listitem>
341         <para>Configuring node hardware and installing the PlanetLab operating
342         system</para>
343       </listitem>
344
345       <listitem>
346         <para>Putting a node into a debug state so administrators can track
347         down problems</para>
348       </listitem>
349
350       <listitem>
351         <para>Reconfiguring an already installed node to reflect new hardware,
352         or changed network settings</para>
353       </listitem>
354
355       <listitem>
356         <para>Booting an already installed node into the PlanetLab operating
357         system</para>
358       </listitem>
359     </itemizedlist>
360
361     <section>
362       <title>Flow Chart</title>
363
364       <para>Below is a high level flow chart of the boot manager, from the
365       time it is executed to when it exits. This core state machine is located
366       in source/BootManager.py.</para>
367
368       <para><figure>
369           <title>Boot Manager Flow Chart</title>
370
371           <mediaobject>
372             <imageobject>
373               <imagedata align="left" fileref="boot-manager-flowchart.png"
374                          scalefit="1" />
375             </imageobject>
376           </mediaobject>
377         </figure></para>
378
379       <para></para>
380     </section>
381
382     <section>
383       <title>Example Session Sequence</title>
384
385       <para><figure>
386           <title>Boot Manager Session Sequence Diagram</title>
387
388           <mediaobject>
389             <imageobject>
390               <imagedata align="left" fileref="bootmanager-sequence.png"
391                          scalefit="1" />
392             </imageobject>
393           </mediaobject>
394         </figure></para>
395     </section>
396
397     <section>
398       <title>Boot CD Environment</title>
399
400       <para>The boot manager needs to be able to operate under all currently
401       supported boot cds. The new 3.0 cd contains software the current 2.x cds
402       do not contain, including the Logical Volume Manager (LVM) client tools,
403       RPM, and YUM, among other packages. Given this requirement, the boot cd
404       will need to download as necessary the extra support files it needs to
405       run. Depending on the size of these files, they may only be downloaded
406       by specific steps in the flow chart in figure 1, and thus are not
407       mentioned.</para>
408
409       <para>See the PlanetLab BootCD Documentation for more information about
410       the current, 3.x boot cds, how they are build, and what they provide to
411       the BootManager.</para>
412     </section>
413
414     <section>
415       <title>Node Configuration Files</title>
416
417       <para>To remain compatible with 2.x boot cds, the format and existing
418       contents of the configuration files for the nodes will not change. There
419       will be, however, the addition of three fields:</para>
420
421       <orderedlist>
422         <listitem>
423           <para>NET_DEVICE</para>
424
425           <para>If present, use the device with the specified mac address to
426           contact PLC. The network on this device will be setup. If not
427           present, the device represented by 'eth0' will be used.</para>
428         </listitem>
429
430         <listitem>
431           <para>NODE_KEY</para>
432
433           <para>The unique, per-node key to be used during authentication and
434           identity verification. This is a fixed length, random value that is
435           only known to the node and PLC.</para>
436         </listitem>
437
438         <listitem>
439           <para>NODE_ID</para>
440
441           <para>The PLC assigned node identifier.</para>
442         </listitem>
443       </orderedlist>
444
445       <para>An example of a configuration file for a dhcp networked
446       machine:</para>
447
448       <programlisting>IP_METHOD="dhcp"
449 HOST_NAME="planetlab-1"
450 DOMAIN_NAME="cs.princeton.edu"
451 NET_DEVICE="00:06:5B:EC:33:BB"
452 NODE_KEY="79efbe871722771675de604a227db8386bc6ef482a4b74"
453 NODE_ID="121"</programlisting>
454
455       <para>An example of a configuration file for the same machine, only with
456       a statically assigned network address:</para>
457
458       <programlisting>IP_METHOD="static"
459 IP_ADDRESS="128.112.139.71"
460 IP_GATEWAY="128.112.139.65"
461 IP_NETMASK="255.255.255.192"
462 IP_NETADDR="128.112.139.127"
463 IP_BROADCASTADDR="128.112.139.127"
464 IP_DNS1="128.112.136.10"
465 IP_DNS2="128.112.136.12"
466 HOST_NAME="planetlab-1"
467 DOMAIN_NAME="cs.princeton.edu"
468 NET_DEVICE="00:06:5B:EC:33:BB"
469 NODE_KEY="79efbe871722771675de604a227db8386bc6ef482a4b74"
470 NODE_ID="121"</programlisting>
471     </section>
472   </section>
473
474   <section>
475     <title>BootManager Configuration</title>
476
477     <para>All run time configuration options for the BootManager exist in a
478     single file located at source/configuration. These values are described
479     below.</para>
480
481     <itemizedlist>
482       <listitem>
483         <para><literal>VERSION</literal></para>
484
485         <para>The current BootManager version. During install, written out to
486         /etc/planetlab/install_version</para>
487       </listitem>
488
489       <listitem>
490         <para><literal>BOOT_API_SERVER</literal></para>
491
492         <para>The full URL of the API server to contact for authenticated
493         operations.</para>
494       </listitem>
495
496       <listitem>
497         <para><literal>TEMP_PATH</literal></para>
498
499         <para>A writable path on the boot cd we can use for temporary storage
500         of files.</para>
501       </listitem>
502
503       <listitem>
504         <para><literal>SYSIMG_PATH</literal></para>
505
506         <para>The path were we will mount the node logical volumes during any
507         step that requires access to the disks.</para>
508       </listitem>
509
510       <listitem>
511         <para>CACERT_PATH</para>
512
513         <para>Variable not used anymore.</para>
514       </listitem>
515
516       <listitem>
517         <para><literal>NONCE_FILE</literal></para>
518
519         <para>Variable not used anymore.</para>
520       </listitem>
521
522       <listitem>
523         <para><literal>PLCONF_DIR</literal></para>
524
525         <para>The path that PlanetLab node configuration files will be created
526         in during install. This should not be changed from /etc/planetlab, as
527         this path is assumed in other PlanetLab components.</para>
528       </listitem>
529
530       <listitem>
531         <para><literal>SUPPORT_FILE_DIR</literal></para>
532
533         <para>A path on the boot server where per-step additional files may be
534         located. For example, the packages that include the tools to allow
535         older 2.x version boot cds to partition disks with LVM.</para>
536       </listitem>
537
538       <listitem>
539         <para><literal>ROOT_SIZE</literal></para>
540
541         <para>During install, this sets the size of the node root partition.
542         It must be large enough to house all the node operational software. It
543         does not store any user/slice files. Include 'G' suffix in this value,
544         indicating gigabytes.</para>
545       </listitem>
546
547       <listitem>
548         <para><literal>SWAP_SIZE</literal></para>
549
550         <para>How much swap to configure the node with during install. Include
551         'G' suffix in this value, indicating gigabytes.</para>
552       </listitem>
553
554       <listitem>
555         <para><literal>SKIP_HARDWARE_REQUIREMENT_CHECK</literal></para>
556
557         <para>Whether or not to skip any of the hardware requirement checks,
558         including total disk and memory size constraints.</para>
559       </listitem>
560
561       <listitem>
562         <para><literal>MINIMUM_MEMORY</literal></para>
563
564         <para>How much memory is required by a running PlanetLab node. If a
565         machine contains less physical memory than this value, the install
566         will not proceed.</para>
567       </listitem>
568
569       <listitem>
570         <para><literal>MINIMUM_DISK_SIZE</literal></para>
571
572         <para>The size of the small disk we are willing to attempt to use
573         during the install, in gigabytes. Do not include any suffixes.</para>
574       </listitem>
575
576       <listitem>
577         <para><literal>TOTAL_MINIMUM_DISK_SIZE</literal></para>
578
579         <para>The size of all usable disks must be at least this sizse, in
580         gigabytes. Do not include any suffixes.</para>
581       </listitem>
582
583       <listitem>
584         <para><literal>INSTALL_LANGS</literal></para>
585
586         <para>Which language support to install. This value is used by RPM,
587         and is used in writting /etc/rpm/macros before any RPMs are
588         installed.</para>
589       </listitem>
590
591       <listitem>
592         <para><literal>NUM_AUTH_FAILURES_BEFORE_DEBUG</literal></para>
593
594         <para>How many authentication failures the BootManager is willing to
595         except for any set of calls, before stopping and putting the node into
596         a debug mode.</para>
597       </listitem>
598     </itemizedlist>
599   </section>
600
601   <section>
602     <title>Installer Hardware Detection</title>
603
604     <para>When a node is being installed, the Boot Manager must identify which
605     hardware the machine has that is applicable to a running node, and
606     configure the node properly so it can boot properly post-install. The
607     general procedure for doing so is outline in this section. It is
608     implemented in the <filename>source/systeminfo.py</filename> file.</para>
609
610     <para>The process for identifying which kernel module needs to be load
611     is:</para>
612
613     <orderedlist>
614       <listitem>
615         <para>Create a lookup table of all modules, and which PCI ids
616         coorespond to this module.</para>
617       </listitem>
618
619       <listitem>
620         <para>For each PCI device on the system, lookup its module in the
621         first table.</para>
622       </listitem>
623
624       <listitem>
625         <para>If a module is found, put in into one of two categories of
626         modules, either network module or scsi module, based on the PCI device
627         class.</para>
628       </listitem>
629
630       <listitem>
631         <para>For each network module, write out an 'eth&lt;index&gt;' entry
632         in the modprobe.conf configuration file.</para>
633       </listitem>
634
635       <listitem>
636         <para>For each scsi module, write out a
637         'scsi_hostadapter&lt;index&gt;' entry in the modprobe.conf
638         configuration file.</para>
639       </listitem>
640     </orderedlist>
641
642     <para>This process is fairly straight forward, and is simplified by the
643     fact that we currently do not need support for USB, sound, or video
644     devices when the node is fully running. The boot cd itself uses a similar
645     process, but includes USB devices. Consult the boot cd technical
646     documentation for more information.</para>
647
648     <para>The creation of the PCI id to kernel module table lookup uses three
649     different sources of information, and merges them together into a single
650     table for easier lookups. With these three sources of information, a
651     fairly comprehensive lookup table can be generated for the devices that
652     PlanetLab nodes need to have configured. They include:</para>
653
654     <orderedlist>
655       <listitem>
656         <para>The installed <filename>/usr/share/hwdata/pcitable
657         </filename>file</para>
658
659         <para>Created at the time the hwdata rpm was built, this file contains
660         mappings of PCI ids to devices for a large number of devices. It is
661         not necessarily complete, and doesn't take into account the modules
662         that are actually available by the built PlanetLab kernel, which is a
663         subset of the full set available (again, PlanetLab nodes do not have a
664         use for network or video drivers, and thus are not typically
665         built).</para>
666       </listitem>
667
668       <listitem>
669         <para>From the built kernel, the <filename>modules.pcimap</filename>
670         from the <filename>/lib/modules/&lt;kernelversion&gt;/</filename>
671         directory.</para>
672
673         <para>This file is generated at the time the kernel is installed, and
674         pulls the PCI ids out of each module, for the modules list they
675         devices they support. Not all modules list all devices they sort, and
676         some contain wild cards (that match any device of a single
677         manufacturer).</para>
678       </listitem>
679
680       <listitem>
681         <para>From the built kernel, the <filename>modules.dep</filename> from
682         the <filename>/lib/modules/&lt;kernelversion&gt;/</filename>
683         directory.</para>
684
685         <para>This file is also generated at the time the kernel is installed,
686         but lists the dependencies between various modules. It is used to
687         generate a list of modules that are actually available.</para>
688       </listitem>
689     </orderedlist>
690
691     <para>It should be noted here that SATA (Serial ATA) devices have been
692     known to exist with both a PCI SCSI device class, and with a PCI IDE
693     device class. Under linux 2.6 kernels, all SATA modules need to be listed
694     in modprobe.conf under 'scsi_hostadapter' lines. This case is handled in
695     the hardware loading scripts by making the assumption that if an IDE
696     device matches a loadable module, it should be put in the modprobe.conf
697     file, as 'real' IDE drivers are all currently built into the kernel, and
698     do not need to be loaded. SATA devices that have a PCI SCSI device class
699     are easily identified.</para>
700
701     <para>It is enssential that the modprobe.conf configuration file contain
702     the correct drivers for the disks on the system, if they are present, as
703     during kernel installation the creation of the initrd (initial ramdisk)
704     which is responsible for booting the system uses this file to identify
705     which drivers to include in it. A failure to do this typically results in
706     an kernel panic at boot with a 'no init found' message.</para>
707   </section>
708
709   <section>
710     <title>Common Scenarios</title>
711
712     <para>Below are common scenarios that the BootManager might encounter that
713     would exist outside of the documented procedures for handling nodes. A
714     full description of how they will be handled by the BootManager follows
715     each.</para>
716
717     <itemizedlist>
718       <listitem>
719         <para>A configuration file from previously installed and functioning
720         node is copied or moved to another machine, and the networks settings
721         are updated on it (but the key and node_id is left the same).</para>
722
723         <para>Since the authentication for a node consists of matching not
724         only the node id, but the primary node ip, this step will fail, and
725         the node will not allow the boot manager to be run. Instead, the new
726         node must be created at PLC first, and a network configuration file
727         for it must be generated, with its own node key.</para>
728       </listitem>
729
730       <listitem>
731         <para>After a node is installed and running, the administrators
732         mistakenly remove the cd and media containing the configuration
733         file.</para>
734
735         <para>The node installer clears all boot records from the disk, so the
736         node will not boot. Typically, the bios will report no operating
737         system.</para>
738       </listitem>
739
740       <listitem>
741         <para>A new network configuration file is generated on the website,
742         but is not put on the node.</para>
743
744         <para>Creating a new network configuration file through the PLC
745         interfaces will generate a new node key, effectively invalidating the
746         old configuration file (still in use by the machine). The next time
747         the node reboots and attempts to authentication with PLC, it will
748         fail. After two consecutive authentication failures, the node will
749         automatically put itself into debug mode. In this case, regardless of
750         the API function being called that was unable to authentication, the
751         software at PLC will automatically notify the PlanetLab
752         administrators, and the contacts at the site of the node was able to
753         be identified (usually through its IP address or node_id by searching
754         PLC records.).</para>
755       </listitem>
756     </itemizedlist>
757   </section>
758 </article>