Changes between Initial Version and Version 1 of GENIExperimenter/Tutorials/GENI-SAVI/Execute


Ignore:
Timestamp:
05/22/15 15:16:03 (9 years ago)
Author:
acb@cs.princeton.edu
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • GENIExperimenter/Tutorials/GENI-SAVI/Execute

    v1 v1  
     1= [wiki:GENIExperimenter/Tutorials/GENIExperimentEngine Get to Know the GENI Experiment Engine] =
     2{{{
     3#!html
     4<table border="0">
     5   
     6      <tr>
     7         <td>
     8         <a href="http://groups.geni.net/geni/wiki/GENIExperimenter/Tutorials/GENIExperimentEngine/DesignSetup"> <img border="0" src="http://groups.geni.net/geni/attachment/wiki/GENIExperimenter/Tutorials/Graphics/design.2.png?format=raw" alt="Hello GENI index"  height="90" />  </a>
     9       </td>
     10       <td>
     11         <a href="http://groups.geni.net/geni/wiki/GENIExperimenter/Tutorials/GENIExperimentEngine/Execute"> <img border="0" src="http://groups.geni.net/geni/attachment/wiki/GENIExperimenter/Tutorials/Graphics/execute_on.2.png?format=raw" alt="Hello GENI index"  height="90" />  </a>
     12       </td>
     13       <td>
     14         <a href="http://groups.geni.net/geni/wiki/GENIExperimenter/Tutorials/GENIExperimentEngine/Finish"> <img border="0" src="http://groups.geni.net/geni/attachment/wiki/GENIExperimenter/Tutorials/Graphics/finish.2.png?format=raw" alt="Hello GENI index"  height="90" />  </a>
     15       </td>
     16     </tr>
     17 </table>
     18}}}
     19
     20----
     21
     22= STEPS FOR EXECUTING EXERCISE =
     23
     24----
     25
     26'''Your goal in this tutorial is to fetch a parameterized URL on each node of your slicelet:'''
     27
     28 '''!http://www.lively-web.org/nodejs/GEETutorial/helloWorld?slice=<slice name>&name=<container name>&ip=<IP of host>&local=<IP of  container>&lat=<latitude of host>&lng=<longitude of container>'''
     29
     30'''This page will log each of your queries, and you can check that all your nodes were successfully able to run the query.'''
     31
     32You will use Ansible to do this. 
     33
     34== 1. Create an Ansible playbook to download a parameterized URL from each node ==
     35
     36To solve the problems of this tutorial, you need to collect several pieces of information on each node: the container name, the IP of the host (i.e., the VM hosting the container), the IP of the container, and the latitude and longitude of the host.  Three of these (the slice name, container name, and local IP) can be found from Ansible variables.  Running a {{{setup}}} command, as on the previous page, will show you the Ansible variables.  Note that {{{setup}}} is run automatically by Ansible, so when executing a playbook on a node that information is available.  Look through the output from {{{setup}}}, and you can identify
     37the variables you'll need.  You then need to fetch a custom URL containing this information from each host.   
     38
     39Below is a [attachment:gee-tutorial.yaml skeleton Ansible playbook] that you can use.  You will need to fill in the bits marked `# INSERT ARGUMENTS HERE`, and further instructions on how to do this are included below the skeleton playbook.  If you get stuck at any point, you can take a look at this [attachment:gee-tutorial-solution.yaml solution] -- but don't give up too easily!
     40
     41{{{
     42#!python
     43---
     44- hosts: nodes
     45  remote_user: root
     46  tasks:
     47
     48  ### (a): Get the container's FQDN ###
     49  - name: Dump container FQDN
     50    debug: # INSERT ARGUMENTS HERE
     51
     52
     53  ### (b):  Get the container IP address ###
     54  - name: Dump container IP address
     55    debug: # INSERT ARGUMENTS HERE
     56
     57
     58  ### (c): Get the control host name ###
     59  - name: Dump control host name
     60    debug: # INSERT ARGUMENTS HERE
     61
     62
     63  ### (d): Get the host's public IP address ###
     64  - name: Get my public IP using 'dig +short'
     65    shell: # INSERT ARGUMENTS HERE
     66    register: public_ip
     67
     68  - name: Dump public_ip variable
     69    debug: var=public_ip
     70
     71
     72  ### (e): Get the latitude and longitude for each node ###
     73  - name: Download GeoLiteCity DB
     74    get_url: # INSERT ARGUMENTS HERE
     75
     76  - name: Unzip GeoLiteCity.dat.gz
     77    shell: gunzip -f GeoLiteCity.dat.gz
     78
     79  - name: Run geoiplookup to get latitude
     80    shell: # INSERT ARGUMENTS HERE
     81    register: latitude
     82
     83  - name: Dump latitude variable
     84    debug: var=latitude
     85
     86  - name: Run geoiplookup to get longitude
     87    shell: # INSERT ARGUMENTS HERE
     88    register: longitude
     89
     90  - name: Dump longitude variable
     91    debug: var=longitude
     92
     93
     94  ### (f): Fetch the parameterized URL ###
     95  - name: Dump the full URL, to make sure it looks OK
     96    debug: msg="http://www.lively-web.org/nodejs/GEETutorial/helloWorld?slice=# INSERT ARGUMENTS HERE"
     97
     98  - name: Fetch the full URL
     99    shell: curl "http://www.lively-web.org/nodejs/GEETutorial/helloWorld?slice=# INSERT ARGUMENTS HERE"
     100}}}
     101
     102The following subsections provide further guidance on how to complete each step.
     103
     104=== (a) Get the container's FQDN ===
     105
     106Look at the variables collected by Ansible's '''setup''' module.  Find one that holds the container's fully-qualified domain name (e.g., slice347.pcvm1-1.instageni.iu.edu) and dump it using a '''debug''' task. 
     107
     108=== (b) Get the container IP address ===
     109
     110Look at the variables collected by Ansible's '''setup''' module.  Find one that holds the container IP address and dump it using a '''debug''' task.
     111
     112=== (c) Get the control host name ===
     113
     114Look at the variables collected by Ansible's '''setup''' module.  Find one that holds the control host's FQDN (HINT: it begins with ''pcvm'') and dump it using a '''debug''' task.  You'll need this for the next step.
     115
     116=== (d) Get the host's public IP address ===
     117
     118The IP address visible inside the slicelet (as reported in the variable ''ansible_eth0.ipv4.address'') is a private address -- it is not the control address of the host.  To discover the ''public'' IP address of the node, run '''dig +short <control host name>'''.
     119
     120|| [[Image(wiki:GENIExperimenter/Tutorials/Graphics:tip.png, nolink, 50px, bottom)]] || '''Pro Tip:''' The '''ansible''' command-line tool is a good way to try out Ansible tasks before putting them in your playbook.  Look at the examples in part 1 above. ||
     121
     122|| [[Image(wiki:GENIExperimenter/Tutorials/Graphics:tip.png, nolink, 50px, bottom)]] || '''Pro Tip:''' Running a playbook on all the nodes can take a fair amount of time, and this can lengthen the debug cycle.  Pick one or two nodes to be {{{debug_nodes}}}, then go to the {{{ansible-hosts}}} inventory file and add the lines
     123{{{
     124#!python
     125[debug_nodes]
     126    <slice-name>.pcvm3-1.geni.case.edu ansible_ssh_host=pcvm3-1.geni.case.edu ansible_ssh_port=49153
     127     <slice-name>.pcvm2-2.instageni.rnoc.gatech.edu ansible_ssh_host=pcvm2-2.instageni.rnoc.gatech.edu ansible_ssh_port=49153
     128}}}
     129to the top.  Then, first run every playbook on {{{debug_nodes}}} for your tests.
     130 ||
     131
     132|| [[Image(wiki:GENIExperimenter/Tutorials/Graphics:tip.png, nolink, 50px, bottom)]] || '''Pro Tip:''' Usually in an Ansible playbook you reference a variable by surrounding it in double curly brackets: ''{{ ansible_eth0.ipv4.address }}''.  You can see examples of how variables are referenced in tasks in [https://github.com/ansible/ansible-examples/blob/master/language_features/get_url.yml this playbook]. ||
     133
     134|| [[Image(wiki:GENIExperimenter/Tutorials/Graphics:tip.png, nolink, 50px, bottom)]] || '''Pro Tip:''' When you run an Ansible command in a playbook, you can save the output into a new variable using '''register: varname'''  Then you can retrieve the value later in the playbook using ''{{ varname }}'' or, for shell command output, ''{{ varname.stdout }}''.  You can see an example of how to register a variable in [https://github.com/ansible/ansible-examples/blob/master/language_features/register_logic.yml this playbook]. ||
     135
     136=== (e) Get the latitude and longitude for each node ===
     137
     138To map the host's control IP address obtained in the previous step to the latitude and longitude for each node, use the '''geoiplookup''' tool, provided by package '''geoip-bin'''.
     139
     140{{{
     141$ geoiplookup -f <data file> <ip address>
     142}}}
     143
     144where ''<data file>'' is the database of IP addresses and locations.  You can find a good one at: http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz, which you’ll have to download to each node and unzip.   
     145
     146Note that '''geoiolookup''' returns a bunch of comma-separated fields.  The latitude and longitude are in fields 7 and 8.  You'll need to extract these -- perhaps by piping the output of '''geoiplookup''' into '''awk'''.
     147
     148|| [[Image(wiki:GENIExperimenter/Tutorials/Graphics:tip.png, nolink, 50px, bottom)]] || '''Pro Tip:''' You can also use the Ansible '''script''' module to run arbitrary scripts in your slicelet, if that helps.  See: http://docs.ansible.com/script_module.html ||
     149
     150=== (f) Fetch the parameterized URL ===
     151
     152At this point, you should have enough information to fetch the parameterized URL in the playbook.  You should first use a '''debug''' task to print out the URL to make sure that it's formatted correctly.
     153
     154
     155|| [[Image(wiki:GENIExperimenter/Tutorials/Graphics:tip.png, nolink, 50px, bottom)]] || '''Pro Tip:''' Solve the problem on one node in your slice first, then deploy your solution to the remaining nodes.  ||
     156
     157|| [[Image(wiki:GENIExperimenter/Tutorials/Graphics:tip.png, nolink, 50px, bottom)]] || '''Pro Tip:''' Build your solution a piece at a time.  Get each step working before continuing to the next step. ||
     158----
     159
     160== 2. Run the playbook ==
     161
     162Once you have finished with Step 1, run your playbook against all the nodes in your slicelet! 
     163
     164----
     165
     166== 3. Verify that your playbook worked as expected ==
     167
     168Once you have completed the tutorial, you can check where you’ve said hello from at:
     169
     170  http://lively-web.org/users/rick/GEETutorialMap.html
     171
     172Choose your slicelet name from the drop-down and you should see pins in the map at the coordinates reported by the nodes!
     173
     174----
     175
     176= [wiki:GENIExperimenter/Tutorials/GENIExperimentEngine/Finish Next: Teardown Experiment] =