2 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
8 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
12 <style type="text/css">
30 div, address, ol, ul, li, option, select {
42 font-family: Verdana, sans-serif;
44 background-color: #ffffff;
49 -moz-force-broken-image-icon: 1;
54 background-color: #f3f3f3 !important;
66 border-top: 1px solid #ccc;
67 border-left: 1px solid #ccc;
68 border-right: 2px solid #bbb;
69 border-bottom: 2px solid #bbb;
70 width: 648px !important;
71 margin: 15px auto 25px;
78 * html.pageview body {
81 /* Prevent repaint errors when scrolling in Safari. This "Star-7" css hack
82 targets Safari 3.1, but not WebKit nightlies and presumably Safari 4.
83 That's OK because this bug is fixed in WebKit nightlies/Safari 4 :-). */
84 html*#wys_frame::before {
100 .br_fix br:not(:-moz-last-node):not(:-moz-first-node) {
109 position: static !important
113 h6 { font-size: 8pt }
114 h5 { font-size: 8pt }
115 h4 { font-size: 10pt }
116 h3 { font-size: 12pt }
117 h2 { font-size: 14pt }
118 h1 { font-size: 18pt }
120 blockquote {padding: 10px; border: 1px #DDD dashed }
126 page-break-after: always;
127 /* We don't want this to be resizeable, so enforce a width and height
129 height: 1px !important;
130 width: 100% !important;
134 border-top: 1px dashed #C0C0C0;
135 border-bottom: 1px dashed #C0C0C0;
138 div.google_header, div.google_footer {
145 /* Table of contents */
146 .editor div.writely-toc {
147 background-color: #f3f3f3;
148 border: 1px solid #ccc;
154 ol.writely-toc-subheading {
159 * html writely-toc ol {
160 list-style-position: inside;
163 list-style-type: none;
165 .writely-toc-decimal {
166 list-style-type: decimal;
168 .writely-toc-upper-alpha {
169 list-style-type: upper-alpha;
171 .writely-toc-lower-alpha {
172 list-style-type: lower-alpha;
174 .writely-toc-upper-roman {
175 list-style-type: upper-roman;
177 .writely-toc-lower-roman {
178 list-style-type: lower-roman;
181 list-style-type: disc;
184 /* end default css */
187 /* default print css */
195 div.google_header, div.google_footer {
202 flow: static(header);
205 /* used to insert page numbers */
206 div.google_header::before, div.google_footer::before {
212 flow: static(footer);
215 /* always consider this element at the start of the doc */
217 flow: static(footer, start);
220 span.google_pagenumber {
221 content: counter(page);
224 span.google_pagecount {
225 content: counter(pages);
229 callout.google_footnote {
231 display: prince-footnote;
232 footnote-style-position: inside;
233 /* These styles keep the footnote from taking on the style of the text
234 surrounding the footnote marker. They can be overridden in the
237 font-family: Verdana;
242 /* Table of contents */
243 #WritelyTableOfContents a::after {
244 content: leader('.') target-counter(attr(href), page);
247 #WritelyTableOfContents a {
248 text-decoration: none;
255 content: flow(header);
258 content: flow(footer);
261 border-top: solid black thin;
265 /* end default print css */
278 font-family: Verdana;
282 background-color: #ffffff;
284 /* end ui edited css */
289 .editor a:visited {color: #551A8B}
290 .editor table.zeroBorder {border: 1px dotted gray}
291 .editor table.zeroBorder td {border: 1px dotted gray}
292 .editor table.zeroBorder th {border: 1px dotted gray}
295 .editor div.google_header, .editor div.google_footer {
296 border: 2px #DDDDDD dashed;
302 .editor .misspell {background-color: yellow}
304 .editor .writely-comment {
308 border: 1px dashed #C0C0C0
318 <body onload="DoPageLoad();"
320 revision="dhkdd78p_13kvrgbnfb:231">
327 <B>Geniwrapper Design Document</B>
\r
334 <B>1.0 High Level Overview</B>
\r
340 The purpose of Geniwrapper is to provide a Geni-like interface around the
\r
341 existing planetlab infrastructure. The existing infrastructure consists of two
\r
342 parts: planetlab central (PLC) and planetlab nodes. These two parts map
\r
343 logically into the Geni Registry and Geni Components. However, it is not an
\r
344 exact mapping. Due to the nature of planetlab, some component functionality
\r
345 overlaps with PLC. For example, PLC takes an active role in managing state on
\r
346 planetlab nodes, and therefore some Geni component state exists on PLC,
\r
347 leading to some component APIs to exist on PLC.
\r
353 Geniwrapper is comprised of the following logical modules: <I>utility
\r
354 classes</I>, <I>registry wrapper</I>, <I>component wrapper</I>, and <I>command
\r
355 line client</I>. Client-server communication uses a variant of XML-RPC called
\r
356 the <I>Geni protocol</I>. Section 1 of this document presents a very brief
\r
357 overview of each module. In-depth discussion occurs later.
\r
363 Much of this design adheres to the SFA, and as such this document avoids
\r
364 duplication of the information already presented in the SFA. For example, the
\r
365 description of privileges, which operations are allowed by a specific
\r
366 privileges, and how privileges are assigned to principals is described fully
\r
367 in the SFA and is therefore not duplicated here.
\r
373 NOTE: <b>API documentation</b> is extracted from code comments automatically
\r
374 and is maintained in separate files, one documentation file corresponding to
\r
375 each python source file. An effort has been made to keep API documentation
\r
376 separate from this document, so that the API documentation may be
\r
377 self-maintaining as the code is updated.
\r
383 Geniwrapper is checked into a subversion repository at
\r
384 <A href=http://svn.planetlab.org/geniwrapper>http://svn.planetlab.org/geniwrapper</A>.
\r
385 [TODO: verify link]
\r
392 <B>1.1 Utility classes</B>
\r
398 Utility classes include python classes that implement certificates, GIDs,
\r
399 credentials, and tickets. There are also utility classes for implementing
\r
400 the server and client stubs and the security protocol. The utility modules
\r
401 are designed to be generally re-usable. For example, the credential
\r
402 management class may be used as part of the Geni Registry, Geni Components,
\r
403 and the end-user tools that interact with Geni.
\r
409 The utility classes are located in the
\r
410 <I>util</I> subdirectory.
\r
417 <B>1.2 The registry (PLC) wrapper</B>
\r
423 The registry wrapper is intended to be colocated with PLC. All communication
\r
424 between the registry wrapper and PLC uses the PLCAPI interface and as such,
\r
425 the registry wrapper can be run on a separate machine for ease of development.
\r
426 In addition to the Geni registry operations (register, update, ...), the
\r
427 registry also implements component operations, such as GetTicket, that must be
\r
428 located on PLC due to SFA engineering decisions.
\r
434 The registry wrapper is located in the <I>registry</I> subdirectory
\r
440 TODO: Slice interface shall be implemented in registry wrapper.
\r
446 <B>1.3 The component wrapper</B>
\r
452 The component wrapper is located on planetlab nodes. It implements the
\r
453 component interface, management interface, and portions of the slice
\r
454 interface. Due to SFA engineering decisions, some component operations (i.e.
\r
455 GetTicket) are implemented in the registry wrapper instead of the component
\r
462 The component wrapper is located in the <I>component</I> subdirectory.
\r
468 <B>1.4 Command line client</B>
\r
474 The command line client exports a client interface to Geni that may be used
\r
475 for testing and demonstration purposes. It allows easy invocation of Geni api
\r
476 functions and dumps the results in a human-readable format.
\r
482 The command line client is located in the <I>cmdline</I>
\r
489 <B>1.5 Geni Protocol</B>
\r
495 The Geni protocol is based on XML-RPC. It is implemented primarily in the
\r
496 geniserver.py and geniclient.py files located with the utility classes.
\r
497 Modifications to the XML-RPC protocol include the following:
\r
504 The transport mechanism uses HTTPS instead of HTTP.
\r
506 HTTPS certificate verification is disabled so that custom Geni
\r
507 verification based on GID can be done instead.
\r
509 When an exception occurs on the server, verbose exception information is
\r
510 sent to the client, to assist debugging efforts
\r
523 Authentication of the client by the server is done by using Credentials/GIDs.
\r
524 Generally, each operation contains a credential as the first argument. This
\r
525 credential includes the GID of the caller, which in turn contains the public
\r
526 key of the caller. The server ensures that this public key matches the public
\r
527 key that is being used to decrypt the HTTPS connection, thus ensuring the
\r
528 caller must posess the private key that corresponds to the GID.
\r
534 Authentication of the server by the client is left as an exercise for the
\r
535 client. It may be done easily by specifying the server's public key when the
\r
536 client create the HTTPS connection. This presumes the client knows the public
\r
537 key (or GID) of the server he is trying to connect to.
\r
543 <B>2.0 Utility Classes</B>
\r
549 <B>2.1 Certificates and Keys (cert.py)</B>
\r
555 Geniwrapper uses two crypto libraries: pyOpenSSL and M2Crypto to implement the
\r
556 necessary crypto functionality. Ideally just one of these libraries would be
\r
557 used, but unfortunately each of these libraries is independently lacking. The
\r
558 pyOpenSSL library is missing many necessary functions, and the M2Crypto
\r
559 library has crashed inside of some of the functions. The design decision is to
\r
560 use pyOpenSSL whenever possible as it seems more stable, and only use M2Crypto
\r
561 for those functions that are not possible in pyOpenSSL.
\r
573 Public-private key pairs are implemented by the <B>Keypair </B>class. A
\r
574 Keypair object may represent both a public and private key pair, or it may
\r
575 represent only a public key (this usage is consistent with OpenSSL).
\r
578
\r
581 <B>2.1.2 Certificates</B>
\r
587 The certificate class implements a general purpose X509 certificate, making
\r
588 use of the appropriate pyOpenSSL or M2Crypto abstractions. It also adds
\r
589 several addition features, such as the ability to maintain a chain of parent
\r
590 certificates, and storage of application-specific data.
\r
596 Certificates include the ability to maintain a chain of parents. Each
\r
597 certificate includes a pointer to it's parent certificate. When loaded from a
\r
598 file or a string, the parent chain will be automatically loaded. When saving a
\r
599 certificate to a file or a string, the caller can choose whether to save the
\r
600 parent certificates as well.
\r
606 Example creation of a certificate:
\r
612 # create a key for an issuer<BR>
\r
613 issuerKey = Keypair(create=True)<BR>
\r
614 issuerSubject = "testissuer"
\r
620 # create a key for the certificate
\r
623 userKey = KeyPair(create=True)
\r
629 # create the certificate, set the issuer, and
\r
633 cert = Certificate(subject="test")<BR>
\r
634 cert.set_issuer(issuerKey, issuerSubject)
\r
637 cert.set_pubkey(userKey)<BR>
\r
638 cert.sign()
\r
644 <B>2.1.3 Certificate Verification</B>
\r
651 Verification examines a chain of certificates to ensure that each parent
\r
652 signs the child, and that some certificate in the chain is signed by a
\r
653 trusted certificate. Verification is a basic recursion:
\r
655 <PRE> if this_certificate was signed by trusted_certs:<BR> return<BR> else<BR> return verify_chain(parent, trusted_certs)</PRE>
\r
658 At each recursion, the parent is tested to ensure that it did sign the child.
\r
659 If a parent did not sign a child, then an exception is thrown. If the bottom
\r
660 of the recursion is reached and the certificate does not match a trusted root,
\r
661 then an exception is thrown.
\r
664 <BR>
\r
665 <B>2.2 GIDS (gid.py)</B>
\r
671 GIDs are a derivative class of certificates and as such the GID class
\r
672 inherits all the methods of the certificate class. A GID includes a tuple
\r
673 of the following fields:
\r
679 (uuid, hrn, public_key)
\r
685 UUID is a unique identifier and is created by the python uuid module (or the
\r
686 utility function create_uuid() in gid.py).
\r
692 HRN is a human readable name. It is a dotted form similar to a backward domain
\r
693 name. For example, planetlab.us.arizona.bakers.
\r
699 PUBLIC_KEY is the public key of the principal identified by the UUID/HRN. It
\r
700 is a Keypair object as defined in the cert.py module.
\r
706 It is expected that there is a one-to-one pairing between UUIDs and HRN, but
\r
707 it is uncertain how this would be inforced or if it needs to be enforced.
\r
713 <B>2.2.1 Encoding and Decoding</B>
\r
719 The 5 fields of the GID tuple are stored in the subject-alt-name field of
\r
720 the X509 certificate. Two routines are included to package and unpackage these
\r
721 fields: Encode() and Decode(). Encode should be called prior to signing the
\r
722 GID. Decode is automatically called on demand by the various get_*()
\r
729 <B>2.2.2 Verification of GIDs</B>
\r
734 Verification first performs the checks of the certificate class (verifying that
\r
735 each parent signs the child, etc). In addition, GIDs also confirm that the
\r
736 parent's HRN is a prefix of the child's HRN. Verifying these prefixes prevents a
\r
737 rogue authority from signing a GID for a principal that is not a member of that
\r
738 authority. For example, planetlab.us.arizona cannot sign a GID for
\r
739 planetlab.us.princeton.foo.
\r
744 <B>2.3 Credentials (credential.py)</B>
\r
750 Credentials are a derivative class of certificates and as such the credential
\r
751 class inherits all the methods of the certificate class. A credential includes
\r
752 a tuple of the following fields:
\r
758 (GIDCaller, GIDObject, LifeTime, Privileges, Delegate)
\r
764 GIDCaller identifies the holder of the credential. When a credential is
\r
765 presented to a component, the security layer ensures that the client matches
\r
766 the public key that is contained in GIDCaller.
\r
772 GIDObject identifies the object of the credential. This object depends upon
\r
773 the type of the credential. For example, the credential for a user likely has
\r
774 GIDObject == GIDCaller. Credentials for slices would include the GID of the
\r
775 slice in the GIDObject field. Credentials for authorities include the GID of
\r
776 the authority in the GIDObject field.
\r
782 LifeTime is the lifetime of the credential. Currently not implemented; expect
\r
783 to implement it as an expiration date, and refuse credentials beyond that
\r
790 Privileges is a Rights object that describes the rights that are granted to
\r
791 the holder of the credential.
\r
797 Delegate is a True/False bit that indicates whether or not a credential can be
\r
798 delegated to a different caller.
\r
804 <B>2.3.1 Encoding and Decoding</B>
\r
810 The 5 fields of the credential tuple are stored in the subject-alt-name field
\r
811 of the X509 certificate. Two routines are included to package and unpackage
\r
812 these fields: Encode() and Decode(). Encode should be called prior to signing
\r
813 the credential. Decode is automatically called on demand by the various
\r
820 <B>2.3.2 Verification of Credentials</B>
\r
826 In addition to the checks for ordinary certificates, verification of
\r
827 credentials also ensures that the delegate bit was set by each parent in the
\r
828 chain. If a delegate bit was not set, then an exception is thrown. Each
\r
829 credential must also contain a subset of the rights of the parent credential
\r
830 (i.e. a user credential cannot delegate authority rights).<BR>
\r
832 <B>2.4 Rights (rights.py)<BR>
\r
834 </B>Rights are implemented by two classes:<BR>
\r
836 Right - represents a single right<BR>
\r
837 RightList - represents a list of rights A right may allow several different
\r
840 For example, the "info" right allows "listslices", "listcomponentresources",
\r
843 <B>2.5 Records (record.py)</B><BR>
\r
849 The GeniRecord class implements a Geni Record. The GeniRecord class implements
\r
850 an abstract interface for the record, so that a client may use records without
\r
851 having to understant the underlying implementation details, such as whether
\r
852 the record is realized in the registry database, a local cache, or has been
\r
853 transmitted over the wire by an interface. A GeniRecord is a tuple (Name, GID,
\r
860 Name specifies the HRN of the object GID is the GID of the object
\r
866 Type is user | sa | ma | slice | component Info is comprised of the
\r
867 following sub-fields
\r
873 Pointer is a pointer to the record in the PL database
\r
879 pl_info is planetlab-specific info (when talking to client)
\r
885 geni_info = geni-specific info (when talking to client)
\r
891 The pointer is interpreted depending on the type of the record. For example,
\r
892 if the type=="user", then pointer is assumed to be a person_id that indexes
\r
893 into the persons table.
\r
899 A given HRN may have more than one record, provided that the records are of
\r
900 different types. For example, planetlab.us.arizona may have both an SA and a
\r
901 MA record, but cannot have two SA records.
\r
907 <B>2.6 Tickets (geniticket.py)</B>
\r
913 Similar to GIDs and Credentials, tickets also leverage the certificate object.
\r
919 A Ticket is tuple:<BR>
\r
920 (gidCaller, gidObject, attributes, rspec, delegate)<BR>
\r
922 gidCaller = GID of the caller performing the operation<BR>
\r
923 gidObject = GID of the slice<BR>
\r
924 attributes = slice attributes (keys, vref, instantiation,
\r
926 rspec = resources
\r
932 Tickets are created by invoking GetTicket() on the Registry. The slice
\r
933 attributes and rspec are taken from the planetlab slice database and represent
\r
934 the current state of the slice. As of yet, tickets do not include any concept
\r
935 of time -- a ticket represents the state of the slice at the current time
\r
942 Tickets are redeemed by invoking RedeemTicket() on the Registry. The
\r
943 attributes and spec are combined back into a planetlab slice record and handed
\r
944 off to the node manager.
\r
950 Tickets are signed by an authority and include parentage information that
\r
951 traces the chain of authorities back to a trusted root.
\r
957 <B>2.6.1 rspecs</B>
\r
963 The rspec is currently a dictionary of {name: value} pairs. These pairs are
\r
964 taken verbatim from the planetlab slice database.
\r
970 The general rule that is used is that things in the slice record that do not
\r
971 specifically imply a tangible resource (initscripts, keys, etc) are treated as
\r
972 attributes and things that do specify a tangible resource (disk, network, etc)
\r
973 are treated as the rspec.
\r
979 TODO: The definition of an rspec is evolving. It remains to reconcile the
\r
980 eclipse schema with Geniwrapper. Gacks is also using another rspec format,
\r
981 which may be need to be reconciled with the eclipse schema and/or geniwrapper.
\r
988 <B>2.6.2 Encoding and Decoding</B>
\r
994 The 5 fields of the credential tuple are stored in the subject-alt-name
\r
995 field of the X509 certificate. Two routines are included to package and
\r
996 unpackage these fields: Encode() and Decode(). Encode should be called prior
\r
997 to signing the ticket. Decode is automatically called on demand by the
\r
998 various get_*() functions.
\r
1004 <B>2.6.3 Verification of Tickets</B>
\r
1010 Verification uses the standard parentage verification provided by the
\r
1011 certificate class. Specifically, each certificate is signed by a parent, and
\r
1012 some certificate must resolve to the trusted root set that is specified on
\r
1019 Unlike credentials and GIDs, the parent of a ticket may be a degenerate
\r
1020 ticket that does not include the full 5-tuple (caller, object, attributes,
\r
1021 rspec, delegate). In such a case, the parent is just a placeholder in the
\r
1022 chain of authority used to convey the parentage information.
\r
1028 Delegation of tickets is not something that is discussed in the SFA, but it
\r
1029 is supported in the ticket class and may be a useful feature. For example,
\r
1030 Alice may hold a ticket for a particular component, and delegate that ticket
\r
1031 to Bob. Bob could then instantiate a slice for Alice. This may be one way to
\r
1032 implement a slice manager.<BR>
\r
1034 <B>2.7 Hierarchy of Authorities (hierarchy.py)</B><BR>
\r
1036 This module implements a hierarchy of authorities and performs a similar
\r
1037 function as the "tree" module of the original geniwrapper prototype. An HRN
\r
1038 is assumed to be a string of authorities separated by dots. For example,
\r
1039 "planetlab.us.arizona.bakers". Each component of the HRN is a different
\r
1040 authority, with the last component being a leaf in the tree. Each authority
\r
1041 is stored in a subdirectory on the registry.<BR>
\r
1043 Inside this subdirectory are several files:<BR>
\r
1044 *.GID - GID file<BR>
\r
1045 *.PKEY - private key file<BR>
\r
1046 *.DBINFO - database info<BR>
\r
1048 The hierarchy class can be used to create GIDs, Credentials, and Tickets for
\r
1049 a given authority.
\r
1056 The default behavior is that all authorities contained in the hierarchy will
\r
1057 be located together in a single physical registry. However, this is not
\r
1058 strictly necessary. The *.DBINFO files contain the database information for an
\r
1059 authority and can easily be configured to point to other machines. How an
\r
1060 authority would cause the DBINFO files to be installed in the correct places
\r
1061 is left as a separate exercise, possibly via an out-of-band management
\r
1062 interface or a web page.
\r
1066 <B>2.8 Configuration Information (config.py)</B><BR>
\r
1068 This module holds configuration parameters for geniwrapper. There are two main
\r
1069 pieces of information that are used: the database connection and the PLCAPI
\r
1072 Geniwrapper uses a MYSQL database to store records. This database may be
\r
1073 co-located with the PLC database, or it may be a separate database. The
\r
1074 following parameters define the connection to the database. Note that
\r
1075 Geniwrapper does not access any of the PLC databases directly via a mysql
\r
1076 connection; All PLC databases are accessed via PLCAPI.<BR>
\r
1079 Geniwrapper uses a PLCAPI connection to perform operations on the registry,
\r
1080 such as creating and deleting slices. This connection requires an account on
\r
1081 the PLC server with full administrator access. The Url parameter controls
\r
1082 whether the connection uses PLCAPI directly (i.e. Geniwrapper is located on
\r
1083 the same machine as PLC), or uses a XMLRPC connection to the PLC machine. If
\r
1084 you wish to use the API directly, then remove the Url field from the
\r
1089 <B>2.8.1 Database Configuration</B>
\r
1095 Below is an example database configuration from config.py:
\r
1101 def get_default_dbinfo():<BR>
\r
1102 dbinfo={}<BR>
\r
1103 dbinfo['dbname'] = 'planetlab4'<BR>
\r
1104 dbinfo['address'] = 'localhost'<BR>
\r
1105 dbinfo['port'] = 5432<BR>
\r
1106 dbinfo['user'] = 'pgsqluser'<BR>
\r
1107 dbinfo['password'] = '4c77b272-c892-4bdf-a833-dddeeee1a2ed'
\r
1110 return dbinfo
\r
1116 This identifies several important pieces of the database configuration. The
\r
1117 name specifies the database name as used by pgsql. The address is the hostname
\r
1118 (or ip-address) of the machine that is hosting the database. It is most likely
\r
1119 the local machine. Port specifies the socket port where the pgsql is
\r
1120 listening. The user and password authenticate Geniwrapper to the pgsql
\r
1121 database. In this example, an existing PLC database was used. This is not
\r
1122 strictly necessary as only Geni-specific information is stored in this
\r
1123 database. A separate database could be used, on a separate machine than PLC if
\r
1130 <B>2.8.2 PLCAPI Configuration</B>
\r
1136 Blow is an example PLCAPI configuration from config.py:
\r
1142 def get_pl_auth():<BR>
\r
1143 pl_auth = {'Username':
\r
1144 <A href="mailto:'root@198.0.0.132'">'root@198.0.0.132'</A>,<BR>
\r
1145 'AuthMethod': 'password',<BR>
\r
1146 'AuthString': 'root',<BR>
\r
1147 "Url":
\r
1148 "<A href=https://localhost/PLCAPI/>https://localhost:443/PLCAPI/</A>"<BR>
\r
1149 }
\r
1152 return pl_auth
\r
1158 The PLCAPI configuration tells Geniwrapper how to connect to PLC. There are
\r
1159 two options: a local connection or a remote connection. If the Url field is
\r
1160 defined, then a remote connection is assumed, and Geniwrapper will attempt to
\r
1161 connect via XMLRPC to a remote PLCAPI server. If the Url field is not defined,
\r
1162 then Geniwrapper will assume that PYTHONPATH includes the relevant PLCAPI
\r
1163 classes to use PLCAPI directly.
\r
1169 Username specifies the name of the PLCAPI user. It is suggested that a user
\r
1170 with full administrative authority be allowed. Otherwise, Geniwrapper will be
\r
1171 unable to lookup public keys and other information that PLC does not make
\r
1172 available publicly. Administrative permission is also required to create PLC
\r
1173 sites, users, etc. Authmethod and AuthString specify the password require to
\r
1180 <B>3.0 The Registry Wrapper</B>
\r
1186 This wrapper implements the Geni Registry. According to the SFA, the basic
\r
1187 functionality of a registry is to map HRNs into records. However, because of
\r
1188 the interactions between Geniwrapper and PLC, the registry does more than act
\r
1189 as a simple database. The registry performs API calls on PLC that create
\r
1190 slices, sites, users, etc., and as such may indirectly cause slices to be
\r
1191 instantiated on components, because components are also linked to PLC.
\r
1197 The mapping of Geni objects to planetlab objects is relatively
\r
1204 slice = slice
\r
1207 user = person
\r
1210 component = node
\r
1213 sa = site
\r
1216 ma = site
\r
1222 The one part that is slightly counterintuitive is SA and MA, which both map to
\r
1223 the planetlab site object. In a unified registry (a registry that serves as
\r
1224 both slice and component registry), these will map to the same site record in
\r
1225 the PLC database. However, there are two distinct Geni records, one for
\r
1226 the SA and one for the MA.
\r
1232 Registry operations generally authenticate the caller by credential.
\r
1233 There are a few exceptions, and the registry API documents should note
\r
1234 those exceptions.
\r
1240 <B>3.1 Registry Tools</B>
\r
1246 The registry include several additional tools that are used to manage it.
\r
1253 import.py - imports existing PLC records into the registry
\r
1259 nuke.py - deletes all Geni records
\r
1265 <B>3.1 Bootstrapping a Registry</B>
\r
1271 There are several items that need to be done before starting the registry.
\r
1277 1) Update util/config.py to match the parameters of your PLC installation.
\r
1283 2) Import the existing planetlab database, creating the appropriate geni
\r
1284 records. This is done by running the "import.py" tool.
\r
1290 3) Create a "trusted_roots" directory and place the certificate of the root
\r
1291 authority in that directory. Given the defaults in import.py, this certificate
\r
1292 would be named "planetlab.gid". For example, mkdir trusted_roots; cp
\r
1293 authorities/planetlab.gid trusted_roots/
\r
1299 <B>4.0 The Component Wrapper</B>
\r
1303 The Geni Component Wrapper implements the Geni Component Manager. It includes
\r
1304 functions for redeeming tickets, starting/stopping/resetting/deleting slices,
\r
1305 and management such as rebooting the component.
\r
1311 The design of the component differs from the registry wrapper in the respect
\r
1312 that the component wrapper must be located physically on the planetlab node
\r
1313 that it is responsible for. The component wrapper interacts directly with
\r
1314 portions of the node manager code on the node.
\r
1320 <B>4.1 Component Authentication of Credentials</B>
\r
1326 The component authenticates credentials the same way that the registry does.
\r
1327 Specifically, there is a directory of trusted_root certificates (or GIDs) on
\r
1328 the component. Any credential presented to the component must include in it's
\r
1329 parentage some certificate in the set of trusted roots. Otherwise, and
\r
1330 exception is thrown.
\r
1336 <B>4.2 The Ticket interface</B>
\r
1342 The ticket interface is split between the Registry (PLC) and the Component.
\r
1343 This is due to the SFA engineering decisions, specifically that the
\r
1344 authoritative copy of planetlab state is stored on PLC and only cached on the
\r
1345 components. Thus, GetTicket() is implemented on the Registry, and
\r
1346 RedeemTicket() is implemented on the component. InstantiateSlice is not
\r
1347 implemented, as that operation is a combination of GetTicket/RedeemTicket and
\r
1348 would therefore span the Registry and Component.
\r
1354 <B>4.3 Sliver Credentials</B>
\r
1360 A recent Geni Architecture call mentioned the need for sliver credentials. A
\r
1361 sliver credential would be identical to a slice credential, but would 1) only
\r
1362 be redeemable on a particular component, and 2) would resolve to a
\r
1363 trusted_root unique to that component (likely the component's GID
\r
1364 certificate). Sliver credentials would be returned by the RedeemTicket call
\r
1365 and would give the caller the permission required to start and stop the
\r
1372 Sliver credentials are not yet implemented, but their implementation would be
\r
1379 <B>4.4 Bootstrapping the Component Wrapper</B>
\r
1385 The first step is to install some required libraries on the component. These
\r
1386 include the m2crypto and pyopenssl libraries. Installing the actual RPMs for
\r
1387 these libaries on a running component proved difficult due to additional
\r
1388 support packages that require installation (python-devel, etc). For
\r
1389 development purposes, it was sufficient to copy the installed/compiled version
\r
1390 of the libraries from the development machine to the component.
\r
1396 The second step is to copy the files required by the component wrapper to
\r
1397 the node manager. They are copied to the /usr/share/Nodemanager directory. A
\r
1398 list of the files is contained in the copynode.sh script in the component
\r
1405 The third step is to copy the trusted root certificates to the component. They
\r
1406 are stored in /usr/share/Nodemanager/trusted_roots. This should include the
\r
1407 certificate for the registry.
\r
1413 The fourth step is to start the component manager. This is done by
\r
1414 connecting to the component via SSH and running
\r
1415 /usr/share/Nodemanager/component.py.
\r
1419 In a production environment, all of these steps would be integrated into the
\r
1420 DVD boot image for the planetlab node.
\r
1426 <B>5.0 Command-Line Interface</B>
\r
1432 A command-line interface is provided that allows a user to interact with the
\r
1433 Geni Registry and Component. This command line interface is located in the
\r
1434 cmdline directory and can be invoked by running genicli.py. Specifying
\r
1435 "genicli.py help" will display a list of available commands.
\r
1441 <B>5.1 Examples</B>
\r
1447 Several examples of using the CLI are presented in the form of shell scripts
\r
1448 in the cmdline directory. These scripts demonstrate creating slices,
\r
1449 authorities, users, nodes, and getting tickets and redeeming tickets. Rather
\r
1450 than duplicating all of those examples here, a few short examples are
\r
1457 <B>5.1.1 Getting a Credential</B>
\r
1463 python ./genicli.py --username root --credfile None --outfile test.cred
\r
1464 getCredential user planetlab.us.pl.account_test
\r
1470 The credential for planetlab.us.pl.account_test is retrieved and stored in the
\r
1471 local file test.cred. The private ket test.pkey is used when opening the
\r
1472 XMLRPC connection and authenticates the client. test.pkey must match the
\r
1473 public key that is in the GID for the user record for
\r
1474 planetlab.us.pl.account_test.
\r
1480 Sample output: (in human-readable summary)
\r
1486 CREDENTIAL planetlab.us.pl.account_test<BR>
\r
1487 privs: refresh,resolve,info<BR>
\r
1488 gidCaller:<BR>
\r
1489 hrn:
\r
1490 planetlab.us.pl.account_test<BR>
\r
1491 uuid:
\r
1492 276262316202422735940395896620385479122<BR>
\r
1493 gidObject:<BR>
\r
1494 hrn:
\r
1495 planetlab.us.pl.account_test<BR>
\r
1496 uuid:
\r
1497 276262316202422735940395896620385479122<BR>
\r
1498 delegate: False
\r
1507 <B>5.1.2 Resolving a record</B>
\r
1513 python ./genicli.py --username test resolve planetlab.us.pl.account_test
\r
1519 The record for planetlab.us.pl.account_test is retrieved and printed to
\r
1520 stdout. The credential used comes from the local file test.cred.
\r
1526 Sample output: (in human-readable summary)
\r
1532 RECORD planetlab.us.pl.account_test<BR>
\r
1533 hrn: planetlab.us.pl.account_test<BR>
\r
1534 type: user<BR>
\r
1535 gid:<BR>
\r
1536 hrn:
\r
1537 planetlab.us.pl.account_test<BR>
\r
1538 uuid:
\r
1539 276262316202422735940395896620385479122<BR>
\r
1540 pointer: 6<BR>
\r
1541 geni_info:<BR>
\r
1542 email :
\r
1543 <A href=mailto:test@test.com>test@test.com</A><BR>
\r
1544 pl_info:<BR>
\r
1545 bio : None<BR>
\r
1546 first_name : test<BR>
\r
1547 last_name : account<BR>
\r
1548 last_updated : 1222497672<BR>
\r
1549 uuid : None<BR>
\r
1550 roles : ['user']<BR>
\r
1551 title : None<BR>
\r
1552 url : None<BR>
\r
1553 key_ids : [1]<BR>
\r
1554 enabled : True<BR>
\r
1555 slice_ids : [24]<BR>
\r
1556 phone : None<BR>
\r
1557 peer_person_id : None<BR>
\r
1558 role_ids : [30]<BR>
\r
1559 person_id : 6<BR>
\r
1560 date_created : 1219083140<BR>
\r
1561 site_ids : [1]<BR>
\r
1562 peer_id : None<BR>
\r
1563 email :
\r
1564 <A href=mailto:test@test.com>test@test.com</A>
\r
1570 <B>5.1.3 Updating a record</B>
\r
1576 python ./genicli.py --username test update user planetlab.us.pl.account_test
\r
1582 The record for planetlab.us.pl.account_test is updated. The credential used
\r
1583 comes from the local file test.cred. No changes are specified, so the only
\r
1584 thing that should be updated is the expiration time.
\r
1590 <B>5.1.4 Resolving an authority</B>
\r
1596 An authority is an example of an HRN that might resolve to two different
\r
1597 records, an SA and a MA record.
\r
1603 python ./genicli.py --username test resolve planetlab.us.pl
\r
1609 Sample Output: (in human readable summary)
\r
1615 RECORD planetlab.us.pl<BR>
\r
1616 hrn: planetlab.us.pl<BR>
\r
1617 type: sa<BR>
\r
1618 gid:<BR>
\r
1619 hrn: planetlab.us.pl<BR>
\r
1620 uuid:
\r
1621 294786197975089072547582920862317666209<BR>
\r
1622 pointer: 1<BR>
\r
1623 geni_info:<BR>
\r
1624 pi :
\r
1625 ['planetlab.us.pl.Administrator_Default']<BR>
\r
1626 pl_info:<BR>
\r
1627 last_updated : 1224136003<BR>
\r
1628 node_ids : [1]<BR>
\r
1629 site_id : 1<BR>
\r
1630 pcu_ids : []<BR>
\r
1631 max_slices : 100<BR>
\r
1632 ext_consortium_id : None<BR>
\r
1633 peer_site_id : None<BR>
\r
1634 abbreviated_name : plctest<BR>
\r
1635 uuid :
\r
1636 230749975723590978208303655640765327534<BR>
\r
1637 person_ids : [2, 4, 6]<BR>
\r
1638 slice_ids : [24, 1, 2]<BR>
\r
1639 latitude : None<BR>
\r
1640 peer_id : None<BR>
\r
1641 max_slivers : 1000<BR>
\r
1642 is_public : False<BR>
\r
1643 address_ids : []<BR>
\r
1644 name : plctest Central<BR>
\r
1645 url :
\r
1646 <A href=http://198.0.0.132/>http://198.0.0.132/</A><BR>
\r
1647 enabled : True<BR>
\r
1648 longitude : None<BR>
\r
1649 login_base : pl<BR>
\r
1650 date_created : 1209428329<BR>
\r
1652 RECORD planetlab.us.pl<BR>
\r
1653 hrn: planetlab.us.pl<BR>
\r
1654 type: ma<BR>
\r
1655 gid:<BR>
\r
1656 hrn: planetlab.us.pl<BR>
\r
1657 uuid:
\r
1658 294786197975089072547582920862317666209<BR>
\r
1659 pointer: 1<BR>
\r
1660 geni_info:<BR>
\r
1661 operator : []<BR>
\r
1662 owner :
\r
1663 ['planetlab.us.pl.Administrator_Default']<BR>
\r
1664 pl_info:<BR>
\r
1665 last_updated : 1224136003<BR>
\r
1666 node_ids : [1]<BR>
\r
1667 site_id : 1<BR>
\r
1668 pcu_ids : []<BR>
\r
1669 max_slices : 100<BR>
\r
1670 ext_consortium_id : None<BR>
\r
1671 peer_site_id : None<BR>
\r
1672 abbreviated_name : plctest<BR>
\r
1673 uuid :
\r
1674 230749975723590978208303655640765327534<BR>
\r
1675 person_ids : [2, 4, 6]<BR>
\r
1676 slice_ids : [24, 1, 2]<BR>
\r
1677 latitude : None<BR>
\r
1678 peer_id : None<BR>
\r
1679 max_slivers : 1000<BR>
\r
1680 is_public : False<BR>
\r
1681 address_ids : []<BR>
\r
1682 name : plctest Central<BR>
\r
1683 url :
\r
1684 <A href=http://198.0.0.132/>http://198.0.0.132/</A><BR>
\r
1685 enabled : True<BR>
\r
1686 longitude : None<BR>
\r
1687 login_base : pl<BR>
\r
1688 date_created : 1209428329
\r