| 1 | [[PageOutline]] |
| 2 | |
| 3 | = GENI Desktop Project Final Report = |
| 4 | |
| 5 | == I. Major accomplishments == |
| 6 | |
| 7 | The following highlights our major accomplishments for the GENI Desktop project. |
| 8 | |
| 9 | === A. Milestones achieved === |
| 10 | |
| 11 | * Enhanced the functionality of the GENI Desktop and integrated it more tightly with the GENI portal, Flack and OMNI. |
| 12 | |
| 13 | * Modified the GENI Desktop to support "Speaks-for" authentication being developed/supported by the control frameworks and other GENI tools/services. |
| 14 | |
| 15 | * Incorporated user-driven feedback into the GENI Desktop to support new user-requested services and features. |
| 16 | |
| 17 | * Developed new training materials that incorporate the changes made to the GENI Desktop. |
| 18 | |
| 19 | * Integrated and leveraged existing tools and services (e.g., Jacks) into the GENI Desktop for managing topologies, experiments, and results. |
| 20 | |
| 21 | * Collected user feedback regarding usability of the GENI Desktop and made major changes to improve its ease-of-use and aesthetics. |
| 22 | |
| 23 | * Adapted the GENI Desktop archiving service for storing and retrieving experiment results and artifacts from iRoDs to support a new archival service with enhanced features. |
| 24 | |
| 25 | * Enhanced the set of scriptable resource management, instrumentation, and monitoring available to experimenters and other tools. |
| 26 | |
| 27 | * Enabled integration of the GENI Desktop with other experimenter tools. |
| 28 | |
| 29 | * Improved the usability of the GENI Desktop through several enhancements |
| 30 | |
| 31 | * Created documentation and tutorial materials to reflect this latest version of the GENI Desktop. |
| 32 | |
| 33 | === B. Deliverables made === |
| 34 | |
| 35 | * We developed several enhancements to the GENI Desktop -- many supporting what were GENI Portal functions. |
| 36 | |
| 37 | * We enhanced the GENI Desktop's interoperability with OMNI, ExoGENI, InstaGENI, and the iRods service. |
| 38 | |
| 39 | * We enhanced the GENI Desktop to use "Speaks-for" credentials for accessing resources from other GENI components on behalf of users. |
| 40 | |
| 41 | * We implemented the slice verification and configuration testing service. |
| 42 | |
| 43 | * We developed code for super slice support in the GENI Desktop. |
| 44 | |
| 45 | * We developed a completely new user interface for the GENI Desktop which we call "GENI Desktop Lite" that greatly improves the look-and-feel and ease-of-use of the GENI Desktop. |
| 46 | |
| 47 | * We integrated the Jacks tool into the GENI Desktop, enabling users to create topologies and instantiate experiments (i.e., slices) using the Jacks tool. We also integrated the Adopt-A-GENI (AAG) tool into the GENI desktop. |
| 48 | |
| 49 | * We developed and integrated a new archival service into the GENI Desktop that leverages VMs to hold, and later display, the archived experiment state in the same context as it was initially collected and viewed. |
| 50 | |
| 51 | * We designed and implemented a GENI Desktop Command Line Interface (gdcli) that enables users to write scripts that control, manage, and measure the performance of their slices through the GENI Desktop. |
| 52 | |
| 53 | * We demonstrated how the new gdcli can be used by other experimenter tools to integrate with the GENI Desktop. |
| 54 | |
| 55 | * We enhanced several GENI Desktop functions to improve the usability of the GENI Desktop. |
| 56 | |
| 57 | * We developed online documentation for the new gdcli interface and gave a tutorial entitled "Monitoring and Controlling Experiments with GENI Desktop Scripts and Modules" at the GEC 23 conference. |
| 58 | |
| 59 | == II. Description of work performed == |
| 60 | |
| 61 | The following provides a description of the major activities and findings for the project. |
| 62 | |
| 63 | === A. Activities and findings === |
| 64 | |
| 65 | Our activities over the period of this project have resulted in enhanced functionality, |
| 66 | improved ease-of-use, better authentication/security, a redesigned user |
| 67 | interface, and the ability to control the GENI Desktop programmatically |
| 68 | throught scripts. In particular, we: |
| 69 | |
| 70 | * Enhanced the functionality of the GENI Desktop |
| 71 | |
| 72 | * Incorporated support for "Speaks-for" into the GENI Desktop |
| 73 | |
| 74 | * Designed and implemented a slice verification service |
| 75 | |
| 76 | * Designed and implemented a super slice abstraction |
| 77 | |
| 78 | * Developed a new archival services based on Xen VMs to restore entire contexts |
| 79 | |
| 80 | * Redesigned the look-and-feel of the GENI Desktop user interface to make it much easier to use |
| 81 | |
| 82 | * Integrated Jacks and Adopt-A-GENI (AAG) tools into the GENI Desktop |
| 83 | |
| 84 | * Designed and implemented a GENI Desktop Command Line Interface (gdcli) to enable script-based access to GENI Desktop functionality. |
| 85 | |
| 86 | The following describes our major activities. We begin with our efforts to |
| 87 | enhance the slice management functionality |
| 88 | and improve the authentication/authorization used to access the GENI Desktop, and |
| 89 | then move on to describe new functionality added to the GENI Desktop, |
| 90 | followed by a description of our efforts to enhance the look-and-feel of the |
| 91 | GENI Desktop, |
| 92 | our efforts to allow scripting of the GENI Desktop, |
| 93 | and lastly several enhancements with regard to the usability. |
| 94 | |
| 95 | ==== Slice Management Functionality ==== |
| 96 | |
| 97 | We made significant changes to the look and feel of the slice management functionality |
| 98 | in order to make it easier for users to interact with, and control, their |
| 99 | slices. |
| 100 | |
| 101 | The first change was to allow the user to determine which slices appear on |
| 102 | the page. Because users are often members of multiple projects, the system |
| 103 | allows them to view only slices belonging to a particular project. A |
| 104 | related change that we made was to limit the number of slices |
| 105 | that are displayed within a project. Because some users were members of |
| 106 | projects with many slices (sometimes numbering into the hundreds of slices), |
| 107 | we now allow users to select which slices from the project will be shown or |
| 108 | hidden. This allows users to easily focus on the slices that they are |
| 109 | working with at the moment. |
| 110 | |
| 111 | A second important change was the addition of slice operations that allow |
| 112 | users to perform slice operations that otherwise would have had to have been |
| 113 | performed on the GENI portal or in Flack. In particular, users can now create a |
| 114 | slice, assign an RSPEC to a slice (more on that later), and allocate the necessary |
| 115 | resources all from within the GENI Desktop. When a user is done with a |
| 116 | slice, the GENI Desktop can be used to delete the resources associated with a |
| 117 | slice. These operations are performed through the newly designed slice |
| 118 | description page. Each field on the page is "clickable" so that it can be |
| 119 | viewed in more detail and/or edited. New fields include an image |
| 120 | of the topology, an RSPEC field, an aggregate manager field, and an auto-renew |
| 121 | field. The slice status field and the next action field have also been |
| 122 | enhanced to better reflect the slice's current context/status. |
| 123 | |
| 124 | Users are now able to assign an RSPEC to a slice and have the GENI Desktop |
| 125 | instantiate the resources (sliver) specified by the RSPEC. Users can |
| 126 | contribute RSPECs to a public RSPEC list (available for anyone to use), or to |
| 127 | their own private list. When creating an RSPEC to be (re)used in the future, |
| 128 | the user can create a thumbnail image of the topology that will be displayed |
| 129 | along with the slice or while selecting and RSPEC to assign to a slice. This |
| 130 | gives users a visual representation of what the topology looks like so that |
| 131 | the user does not have to mentally parse the textual RSPEC to discover the |
| 132 | topology. |
| 133 | |
| 134 | |
| 135 | ==== Authorization: Supporting "Speaks-for" ==== |
| 136 | |
| 137 | The "Speaks-for" credential allows trusted tools to act for, instead of |
| 138 | acting as, an experimenter to perform certain actions, such as requesting |
| 139 | resources from aggregates, accessing allocated resources, and installing |
| 140 | software on experimental nodes. We enhanced the GENI Desktop to use "Speaks-for" |
| 141 | credentials for accessing resources on behalf of users. Users no longer |
| 142 | need to provide the private key to the GENI Desktop. We implemented an interface |
| 143 | for the user to authorize the GENI Desktop to speak for her/him. A GENI |
| 144 | Desktop-specific certificate is signed using the private key of the user. |
| 145 | Because the whole process happens within the browser on the client side, |
| 146 | the private key never leaves the user's machine. The "Speaks-for" credential |
| 147 | allows the GENI Desktop to talk to aggregates and perform all necessary |
| 148 | actions on behalf of the user. |
| 149 | |
| 150 | ==== New Functionality: Jacks, Archival, Verification and Super Slice Services ==== |
| 151 | |
| 152 | We integrated the Jacks tool into the GENI Desktop. Users can now add |
| 153 | resources to their slices by selecting Jacks in the GENI Desktop which will |
| 154 | direct them to a GENI Desktop page that embeds the Jacks tool and allows them |
| 155 | to allocate the resources (i.e., which uses the OMNI tool). RSPECs |
| 156 | created by Jacks can be saved by the GENI Desktop for future use. |
| 157 | |
| 158 | In addition, we integrated the Adopt-A-GENI (AAG) flow specification module into |
| 159 | the GENI Desktop, allowing users to visually define OpenFlow paths across the |
| 160 | topology that are then sent to the AAG module to be instantiated in the |
| 161 | OpenFlow controller. Although the AAG functionality is logically a distinct |
| 162 | service/tool, the messaging system between windows in the GENI Desktop made |
| 163 | it possible to incorporate this new tool with relatively little effort. In |
| 164 | addition, we were able to add a new AAG Controller node type to the Jacks |
| 165 | wrapper, thereby integrating the AAG controller into the Jacks tool as well. |
| 166 | |
| 167 | The existing archival service in the GENI Desktop leveraged the iRoDs storage |
| 168 | service to store and later retrieve measurement data collected by the GENI |
| 169 | Desktop. A key limitation of this service was the inability to easily (and |
| 170 | quickly) access, view, and make sense of archived measurement data. To |
| 171 | address this need, we developed a new archival service that not only archives |
| 172 | the measurement data, but also archives the software and context used to |
| 173 | display the data. Because the data and the environment needed to view the |
| 174 | data are archived, users can quickly access an archive and view the saved |
| 175 | data using the same tools available at the time the data was collected. |
| 176 | |
| 177 | To support this new archival service, we implemented an archival server that |
| 178 | not only captures the measurement data stored on the global node (where |
| 179 | measurement data is collected), but it also captures the state of the drupal |
| 180 | system used to display the data, including all web server (apache) and |
| 181 | database (mysql) files. GENI Desktop users can request that an archive be |
| 182 | made, which is then sent to the archive server. When a user visits the |
| 183 | archive web page on the archive server, they can select from any of the |
| 184 | archived snapshots. The archive server will dynamically launch a Xen VM, |
| 185 | setup the apache, mysql, and Drupal state needed to view the measurement |
| 186 | data, install the archived measurement data, create login credentials for the |
| 187 | user, and share the credentials with the GD so the user is automatically logged |
| 188 | into the archive VM. The result is that the user is presented with the same |
| 189 | look-and-feel as if they had gone to the global node at the time the snapshot was taken. |
| 190 | |
| 191 | We implemented the slice verification and configuration testing service |
| 192 | as a module in GENI Desktop by taking advantage of the module builder function |
| 193 | of the GENI Desktop. Based on the manifest of an experiment, the verification |
| 194 | service analyzes the topology and performs tests about the interfaces of all |
| 195 | nodes in the experiment. The initial version we implemented checks whether |
| 196 | each interface is up and whether it is reachable from a ping test. |
| 197 | The results are presented in a table showing the status of all the interfaces of |
| 198 | all the nodes in the experiment. |
| 199 | Later versions of the verification service included |
| 200 | additional checks (particularly automated bandwidth checks) and also made it |
| 201 | possible for users to write their own verification scripts to test for things |
| 202 | of importance to their experiment. |
| 203 | |
| 204 | Building a large experiment is a difficult task in GENI, partly because |
| 205 | it is more likely to fail if we create an experiment with a lot of nodes. |
| 206 | At the same time, we may have multiple related experiments and want to |
| 207 | combine these relatively small experiments together to form a large experiment. |
| 208 | We developed a new "super slice" service in the GENI Desktop to support this functionality. |
| 209 | Users can use the GENI Desktop to create a super slice by combining multiple |
| 210 | existing slices together. The GENI Desktop provides a GUI for users to display |
| 211 | multiple slices at the same time and pick any pair of nodes from different |
| 212 | slices to establish a link between them. The Super Slice service in the GENI |
| 213 | Desktop currently can then automatically set up GRE tunnels between these selected pairs of nodes |
| 214 | from different slices. |
| 215 | |
| 216 | ==== A New User Interface: GENI Desktop Lite ==== |
| 217 | |
| 218 | Over the years the number of features and capabilities offered by the GENI |
| 219 | Desktop has continued to expand. Indeed, a key goal of the GENI Desktop was |
| 220 | to provide users with a context for managing all aspects of their experiment |
| 221 | from setup and deployment to monitoring and archiving of measurements and |
| 222 | results. The downside to this expanded functionality is increased complexity |
| 223 | using the tool. |
| 224 | At the same time, the number of experimenters who are using the GENI Desktop to |
| 225 | create, manage, monitor, and control their slices has been grown rapidly, |
| 226 | due, in part, to users being exposed to the GENI Desktop as part |
| 227 | of GENI tutorials, summer camps, demonstrations and online documents and |
| 228 | videos. Feedback from this user group indicated that the extensive |
| 229 | functionality available in GENI Desktop made it difficult for new users to |
| 230 | navigate and use. |
| 231 | |
| 232 | To address this need for a tool that could be easily learned and used by new |
| 233 | users, we completely redesigned the look-and-feel of the GENI Desktop to |
| 234 | reduce complexity and make it simple to create, run, and monitor |
| 235 | experiments. Our new "GENI Desktop (GD) Lite" interface is now the default |
| 236 | interface that users see when they log into the GENI Desktop. |
| 237 | Users can still access the (original) advanced user interface if needed, but in most |
| 238 | cases find that the GD Lite interface is sufficient. |
| 239 | The Lite interface is designed to take users through the lifecycle of an |
| 240 | experiment. The Lite interface starts by helping users create a slice, |
| 241 | assigning resources to the slice, and then giving them access to a simplified |
| 242 | version of the GENI Desktop topology view where they can log in to nodes, run |
| 243 | their experiment, monitor basic traffic types, and archive results. Initial |
| 244 | feedback on the new interface has been extremely positive. |
| 245 | |
| 246 | In addition to a major rewrite of the web code for the user interface, one of the key |
| 247 | challenges that we had to address was automating the global node setup, initialization, |
| 248 | and instrumentation. While these "backend" operations were clearly visible |
| 249 | in the old user interface, they had to be hidden in the new interface. This |
| 250 | meant that the GENI Desktop had to be able to add global nodes into the slice |
| 251 | (one for each aggregate) on the user's behalf. This required working with |
| 252 | the aggregates to support the GENI AM API calls needed to add resources to an |
| 253 | existing slice. In addition, the GENI Desktop needed to be able to initialize and then |
| 254 | instrumentize the slice in the background (i.e., while allowing the user to |
| 255 | view and use the slice in the GENI Desktop). This required changes to the |
| 256 | GENI Desktop to monitor the background initialization/instrumentation |
| 257 | process and incrementally enable functionality as it became available. For |
| 258 | example, while resources are being allocated the GENI Desktop can only display |
| 259 | the topology and the status of the node initialization. As soon as the |
| 260 | initilization completes, the file upload, ssh, and run command functionality become available in the user |
| 261 | interface. Later when the instrumentation completes, functionality such as |
| 262 | displaying basic traffic graphs or archiving measurement data become |
| 263 | available in the user interface. In short, users are now taken directly to the |
| 264 | GENI Desktop topology view, bypassing several setup steps required by the old |
| 265 | user interface. Commonly needed functionality is then automatically added as |
| 266 | it becomes available. As part of the new Lite interface, we also simplified |
| 267 | the design of the web page(s) used to select a predefined RSPEC. |
| 268 | |
| 269 | ==== Programming the Desktop: The GENI Desktop CLI (gdcli) ==== |
| 270 | |
| 271 | The GENI Desktop greatly simplifies the task of instrumenting and monitoring |
| 272 | a users' experiment (slice). However, users could only access the GENI |
| 273 | Desktop via a web interface. In other words, there was not programmatic way |
| 274 | for experimenters or tool developers to leverage the GENI Desktop |
| 275 | functionality. |
| 276 | |
| 277 | To address this need we designed a new interface to the GENI Desktop that |
| 278 | could be used to programatically upload files, run commands, download |
| 279 | measurement graphs, etc --- functions previously only possible via the GENI |
| 280 | Desktop web interface. In particular, we developed an application that runs |
| 281 | on Linux (or other Unix-based systems), Mac, and Window called the gdcli |
| 282 | program that can be used to interact with the GENI Desktop. The gdcli |
| 283 | program can be used to: |
| 284 | |
| 285 | * Upload files to a select set of nodes |
| 286 | * Run a command on a select set of nodes |
| 287 | * Download a traffic measurement graph (as PNG or CSV) from a select set of nodes |
| 288 | * Download a normal file from a select set of nodes |
| 289 | * Get a list of slices |
| 290 | * Check the status of a slice |
| 291 | * Get the topology of a slice |
| 292 | * Validate the setup of a slice |
| 293 | * List the nodes in a slice |
| 294 | * List the links in a slice |
| 295 | |
| 296 | The gdcli program can be called from any scripting language (e.g., |
| 297 | python, perl, sh (bash), .BAT files, etc). As a result, users are able to |
| 298 | write programs in their favorite scripting language that make calls to the |
| 299 | GENI Desktop to upload/download files, download measurement graphs, run |
| 300 | commands, etc. |
| 301 | |
| 302 | There were several challenges that we had to address |
| 303 | while implementing the gdcli scripting interface. |
| 304 | First, we needed a way to make calls to the GENI Desktop server (e.g., to |
| 305 | download a traffic graph, or run a command). To solve this problem we |
| 306 | enhanced the GENI Desktop server to support HTTP posts that included |
| 307 | parameters to the request specifying, for example, the list of traffic graphs to be |
| 308 | downloaded (i.e., the nodes/links names and the types of graphs desired). |
| 309 | We implemented a python backend server specifically designed to process the |
| 310 | request, perform the action, and return the results. |
| 311 | The python backend shares access |
| 312 | with the previous GENI Desktop PHP code to the databases and files used by the |
| 313 | GENI Desktop, thereby ensuring that the results returned by the gdcli are the |
| 314 | same information as would be seen in the GENI Desktop web interface. |
| 315 | |
| 316 | A second challenge was securing the access to, and communication with, the |
| 317 | new python backend server. To ensure communication is secure, all communication |
| 318 | occurs over a secure connection using https. The problem of authorization |
| 319 | requires not only that the user authenticate themselves to the server, but |
| 320 | that the server obtain a "speaks-for" certificate to act on behalf of the |
| 321 | user. Because the existing speaks-for generation tools are designed for |
| 322 | interactive web use, not scripting, we decided to require that users first |
| 323 | authorize a speaks-for using the existing GENI Desktop web interface which |
| 324 | can then be stored and used by the GENI Desktop (and our new backend server) |
| 325 | until the speaks-for expires. However, this does not solve the authorization |
| 326 | problem. To ensure the users has the right to issue commands to our python |
| 327 | backend server, the web interface of the GENI Desktop also creates a secret |
| 328 | key (say at the same time the user authorizes the speaks for) that the user |
| 329 | must store on their local machine. The secret key is used when communicating |
| 330 | with the python backend server to prove that the user has the right to invoke |
| 331 | the requested operations on the GENI Desktop. In that sense, users can think |
| 332 | of the gdcli secret key like an ssh key that must be present on their local |
| 333 | machine in order to access the service. |
| 334 | |
| 335 | A third issue involved handling the results/output of a gdcli request. The |
| 336 | gdcli tool provide two mechanisms for handling the output from a request. |
| 337 | The first, and most simple mechanism, concatenates all the output files/graphs and prints |
| 338 | them to standard output, allowing users to redirect output to other programs |
| 339 | or tools. The second way gdcli handles output is to deposit each graph, |
| 340 | downloaded file, or output from a run command into a different file on the |
| 341 | local machine. Files are automatically assigned names that describe their |
| 342 | content (based on the slice, the aggregate, the node or link, and the type |
| 343 | of graph). Because the naming convention is known to experimenters, they can |
| 344 | easily write scripts that know what filenames to look for, and then feed |
| 345 | those files to the appropriate program for processing (e.g., copying traffic |
| 346 | graphs into a web directory to create a user-defined traffic mashup view). |
| 347 | |
| 348 | ==== Improving the Usability: Continued Improvement ==== |
| 349 | |
| 350 | We made continued improvement on the usability of the GENI Desktop. |
| 351 | |
| 352 | 1) We refactored the GENI Desktop code to make it more robust and extensible. |
| 353 | To make the GENI Desktop more robust and extensible (i.e., easier for users |
| 354 | or third parties to add new functionality), we redesigned, streamlined, |
| 355 | simplified, and consolidated large portions of both the graphical user |
| 356 | interface and the backend services/database that support the GENI Desktop. |
| 357 | In particular, we overhauled the GENI Desktop interface based on HTML5, |
| 358 | removing dependencies on Flash code that were present in the original |
| 359 | implementation. We also streamlined and simplified much of the backend |
| 360 | processing, making it faster and more secure/robust to failures. |
| 361 | |
| 362 | 2) We implemented a new way to view the topology based on JACKS |
| 363 | To be consistent with the JACKs interface used to create GENI topologies, we |
| 364 | added JACKs to the GENI Desktop as a way to view the logical topology. To |
| 365 | allow users to interact with the topology, we enhanced JACKs to send messages |
| 366 | to other GENI Desktop components in response to user interactions with the |
| 367 | topology (e.g., selecting a node). This involved working with the Utah team |
| 368 | to make the GENI Desktop messaging system accept messages from JACKS. |
| 369 | |
| 370 | 3) We developed new support for GENI Desktop account management functions |
| 371 | New account management functions allow users to set the default topology |
| 372 | view, the default modules and other behavior for the account. This simplified |
| 373 | users interaction with their slices. |
| 374 | |
| 375 | 4) We implemented enhanced session management functions for the GENI Desktop. |
| 376 | To make the GENI Desktop more secure, we implemented new session management |
| 377 | functionality that improves security by ensuring the user credential is |
| 378 | stored and is valid only for the current GENI Desktop session. Each new session |
| 379 | requires that new credential information be established with the GENI Desktop |
| 380 | server, but the (re) establishment of this information is largely hidden from |
| 381 | the user. |
| 382 | |
| 383 | 5) We improved the GENI Desktop archive service. |
| 384 | The GENI Desktop allows users to archive measurement data to the GENI |
| 385 | iRods server for future use. To recreate the experience of viewing traffic |
| 386 | data in the GENI Desktop, data and traffic graphs can be archived upon |
| 387 | request from the user. Later, a user can retrieve the archived data using |
| 388 | a Vagrant-based VM provided by the GENI Desktop which downloads the archive and |
| 389 | displays data and graphs in an environment that has the same look and feel as |
| 390 | the GENI Desktop environment that originally displayed the data. |
| 391 | |
| 392 | |
| 393 | === B. Project participants === |
| 394 | |
| 395 | The following individuals are involved with the project in one way or another: |
| 396 | * Jim Griffioen - Project PI |
| 397 | * Zongming Fei - Project Co-PI |
| 398 | * Hussamuddin Nasir - Technician/Programmer |
| 399 | * Charles Carpenter - Technician/Programmer |
| 400 | * Xiongqi Wu - Ph.D. Student |
| 401 | * Jeremy Reed - Ph.D. Student |
| 402 | |
| 403 | === C. Publications (individual and organizational) === |
| 404 | |
| 405 | === D. Outreach activities === |
| 406 | |
| 407 | * We gave a presentation about the GENI Desktop and its features during the Introduction to GENI Instrumentation & Measurement Tools portion of the Getting Started with GENI tutorial at GEC19, GEC 22 and GEC 23. |
| 408 | |
| 409 | * We gave a demo of the latest GENI Desktop features during the demo session at GEC 19, GEC 20, GEC 21, GEC 22, and GEC 23. |
| 410 | |
| 411 | * We gave a tutorial entitled "Monitoring and Controlling Experiments with GENI Desktop Scripts and Modules" at the GEC 23 conference. |
| 412 | |
| 413 | * We developed and posted online-documentation and online-tutorials that describe the new features of the GENI Desktop for users. |
| 414 | |
| 415 | === E. Collaborations === |
| 416 | |
| 417 | * Most of our collaborations have been between the GPO Portal team and the aggregate teams at Utah and RENCI. |
| 418 | |
| 419 | === F. Other Contributions === |