3 #yum -y install python-pip
6 import xml.etree.ElementTree as ET
10 # module for bonfire to connect with sfa (following the Rspec)
11 # inspired by the following documenation :
12 # https://svn.planet-lab.org/wiki/SfaDeveloperDummyTutorial#RunningSFAinDummyflavour
14 # 1) list all the resources from bonfire's point of view
15 # python -c 'import bonfire; print bonfire.bonsources()'
17 # 2) retrieve the url, the name and the key that will currently use by sfa for a compute N°3656 located at fr-inria
18 # python -c 'import bonfire; print bonfire.rsa_user_bonfire("fr-inria", "3656")
20 # 3) create a new user and slice for sfa wrap
21 # python -c 'import bonfire; print bonfire.new_user_slice()
23 # 4) changing the status to running status for the experiment 2911
24 # python -c 'import bonfire; print bonfire.provisioning("2911")
26 # 5) stop virtual machine n°3756 at fr-inira testbed
27 # python -c 'import bonfire; print bonfire.stop_vm("fr-inria", "3756")
29 # 6) create an experiment bonfire with the slice id n°2345423 and the experiment owner : foo+bar.stuff+emulab+professor
30 # python -c 'import bonfire; print bonfire.create_fed4fire_exp("nlebreto", "nlebreto", "desc", "300", "2345423", "foo+bar.stuff+emulab+professor")
34 # ########################################################## #
37 # retrieve the url, the name and the key that will currently use by sfa
38 def rsa_user_bonfire(testbed, num_compute):
39 url = "https://api.integration.bonfire.grid5000.fr/" + "locations/" + testbed + "/computes/" + num_compute
40 pagebonfirecompute = callcurl(url)
41 xmlreduit = ET.fromstring(pagebonfirecompute)
44 for name in xmlreduit:
45 if name.tag == "{http://api.bonfire-project.eu/doc/schemas/occi}groups":
46 hash["name"] = name.text
48 if context.tag == "{http://api.bonfire-project.eu/doc/schemas/occi}authorized_keys":
49 hash["keys"] = context.text
52 # create a new user and slice for sfa wrap
54 n = rsa_user_bonfire("fr-inria", "3656")
55 #url = n["url"] + "." + n["name"]
56 # fix to do add -k id_rsa.pub (pb key convert)
57 url = "topdomain.dummy." + n["name"]
58 txtcreateuser = "sfaadmin.py reg register -x {0} -t user -e {1}@dummy.net".format(url, n["name"])
59 createusersfa = subprocess.Popen(txtcreateuser, shell=True)
60 #slice = n["url"] + "." + n["name"] + "_" + n["name"]
61 slice = "topdomain.dummy." + n["name"] + "_slice"
62 txtslice = "sfaadmin.py reg register -x {0} -t slice -r {1}".format(slice, url)
63 createslice = subprocess.Popen(txtslice, shell=True)
65 # create a experiment bonfire with the slice id and the experiment owner
66 def create_fed4fire_exp(name, groups, description, walltime, slice_id, exp_owner):
67 # fix this to have the exact mapping to retrieve slice
68 # xmldescription='<experiment xmlns="http://api.bonfire-project.eu/doc/schemas/occi"><name>' + name +'</name><groups>' + groups + '</groups><description>' + description + '</description><walltime>' + walltime + '</walltime><status>ready</status><fed4fire><slice_id>' + slice_id + '</slice_id><exp_owner>' + exp_owner + '<exp_owner></fed4fire></experiment>'
69 postexp("https://api.integration.bonfire.grid5000.fr/experiments", '<experiment xmlns="http://api.bonfire-project.eu/doc/schemas/occi"><name>testnlebreto</name><groups>nlebreto</groups><description>sdg</description><walltime>3000</walltime><status>ready</status><fed4fire><slice_id>2345423</slice_id><exp_owner>foo+bar.stuff+emulab+professor<exp_owner></fed4fire></experiment>')
71 # simple post method for request
72 def postexp(url, xmldescription):
73 headers = {'content-type': 'application/vnd.bonfire+xml'}
74 r = requests.post(url, data=xmldescription, headers=headers, verify=False, auth=('nlebreto', 'GDRU_23tc$'))
76 # stop a virtual machine for bonfire
77 # changing the state to stopped state
78 def stop_vm(testbed, num_compute):
79 url = "https://api.integration.bonfire.grid5000.fr/" + "locations/" + testbed + "/computes/" + num_compute
80 xmldescription = '<compute xmlns="http://api.bonfire-project.eu/doc/schemas/occi"><state>stopped</state></compute>'
81 headers = {'content-type': 'application/vnd.bonfire+xml'}
82 requests.put(url, data=xmldescription, headers=headers, verify=False, auth=('nlebreto', 'GDRU_23tc$'))
84 # provisioning : set an experiment to running
85 # changing the status to running status
86 def provisioning(num_experiment):
87 url = "https://api.integration.bonfire.grid5000.fr/experiments/" + num_experiment
88 xmldescription = '<experiment xmlns="http://api.bonfire-project.eu/doc/schemas/occi"><status>running</status></experiment>'
89 headers = {'content-type': 'application/vnd.bonfire+xml'}
90 requests.put(url, data=xmldescription, headers=headers, verify=False, auth=('nlebreto', 'GDRU_23tc$'))
92 # retrieving the url, the name and the keys for a specific compute
93 def rsa_user_bonfire(testbed, num_compute):
94 url = "https://api.integration.bonfire.grid5000.fr/" + "locations/" + testbed + "/computes/" + num_compute
95 pagebonfirecompute = callcurl(url)
96 xmlreduit = ET.fromstring(pagebonfirecompute)
99 for name in xmlreduit:
100 if name.tag == "{http://api.bonfire-project.eu/doc/schemas/occi}groups":
101 hash["name"] = name.text
103 if context.tag == "{http://api.bonfire-project.eu/doc/schemas/occi}authorized_keys":
104 hash["keys"] = context.text
109 r = requests.get(url, verify=False, auth=('nlebreto', 'GDRU_23tc$'))
110 if r.status_code == 200:
113 # create the url page
114 def buildpagehttp(part1, part2, locations):
116 for page in locations:
117 res.append(part1 + page + "/" + part2)
120 def boucle(itemname, xmltree, hashrspec, name):
121 for item in xmltree.findall(itemname):
122 hashrspec[name.text][itemname] = item.text
124 # method to list all information from testbeds
125 def jfedfeat(bonfires, pageurl):
126 pageforstatus = callcurl(pageurl)
127 xmlreduit = ET.fromstring(pageforstatus)
129 itemshost = ["DISK_USAGE", "MEM_USAGE", "CPU_USAGE", "MAX_DISK", "MAX_MEM", "MAX_CPU",
130 "FREE_DISK", "FREE_MEM", "FREE_CPU", "FREE_MEM", "FREE_CPU", "USED_DISK",
131 "USED_MEM", "USED_CPU", "RUNNING_VMS"
133 # retrieve info for xml tree
134 for host in xmlreduit.findall('HOST'):
135 for name in host.findall('NAME'):
136 hashrspec[name.text] = {"name" : name.text}
137 for hostshare in host.findall('HOST_SHARE'):
138 for itemshostname in itemshost:
139 boucle(itemshostname, hostshare, hashrspec, name)
142 for clef in hashrspec:
143 bonfires.append("<node component_manager_id=\"urn:publicid:IDN+topdomain+authority+cm" +
144 " component_id=\"urn:publicid:IDN+topdomain:" + hashrspec[clef]["name"] +
145 "\" component_name=" + hashrspec[clef]["name"] + "exclusive=\"false\">" +
146 " <location country=\"unknown\" longitude=\"123456\" latitude=\"654321\"/>" +
147 " <interface component_id=\"urn:publicid:IDN+ple+interface+node14312:eth0\"/>" +
148 " <available now=\"true\"/>" +
149 " <sliver_type name=\"" + hashrspec[clef]["name"] + "\">" +
150 " <bonfire:initscript name=\"" + hashrspec[clef]["name"] + "\"/>" +
152 for infohost in itemshost:
153 bonfires.append(" <bonfire:attribute name=\"" + infohost + "\"value=\"" + hashrspec[clef][infohost] + "\"/>")
154 bonfires.append("</node>")
156 # remove the useless xml tag version
157 def remove_needless_txt(txt):
159 txt=txt.replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n","\n")
160 txt=txt.replace("<?xml version='1.0' encoding='UTF-8'?>\n","\n")
163 # list all bonfire resources following the sfa specification
166 locations = ["fr-inria", "be-ibbt", "uk-epcc"]
167 urlnetworks = buildpagehttp("https://api.integration.bonfire.grid5000.fr/locations/", "networks", locations)
168 urlstorages = buildpagehttp("https://api.integration.bonfire.grid5000.fr/locations/", "storages", locations)
169 urlcomputes = buildpagehttp("https://api.integration.bonfire.grid5000.fr/locations/", "computes", locations)
172 generatedtime = time.strftime("%FT%T%Z")
173 sfabegin = "<RSpec type=\"SFA\" generated=" + generatedtime + "\">"
174 bonfires.append("<?xml version=\"1.0\"?>")
175 bonfires.append(sfabegin)
176 bonfires.append("<managed_experiments>")
177 manag_exp = remove_needless_txt(callcurl("https://api.bonfire-project.eu/managed_experiments"))
178 bonfires.append(manag_exp)
179 bonfires.append("</managed_experiments><sites><machines>")
180 jfedfeat(bonfires, "http://frontend.bonfire.grid5000.fr/one-status.xml")
181 jfedfeat(bonfires, "http://bonfire.epcc.ed.ac.uk/one-status.xml")
182 jfedfeat(bonfires, "http://bonfire.psnc.pl/one-status.xml")
183 jfedfeat(bonfires, "http://nebulosus.rus.uni-stuttgart.de/one-status.xml")
184 bonfires.append("</machines><networks>")
185 for xmlnetworks in urlnetworks:
186 bonfires.append(remove_needless_txt(callcurl(xmlnetworks)))
187 bonfires.append("</networks><storages>")
188 for xmlstorages in urlstorages:
189 bonfires.append(remove_needless_txt(callcurl(xmlstorages)))
190 bonfires.append("</storages><instance_types><computes>")
191 for xmlcomputes in urlcomputes:
192 bonfires.append(remove_needless_txt(callcurl(xmlcomputes)))
193 bonfires.append("</computes></instance_types></sites><experiments>")
194 exp = callcurl("https://api.integration.bonfire.grid5000.fr/experiments")
195 rexp = remove_needless_txt(exp)
196 bonfires.append(rexp)
197 bonfires.append("</experiments><reservations>")
198 reserv = callcurl("https://api.integration.bonfire.grid5000.fr/locations/fr-inria/reservations")
199 rreserv = remove_needless_txt(reserv)
200 bonfires.append(rreserv)
201 bonfires.append("</reservations>")
202 bonfires.append("</RSpec>")
203 bonfires = "\n".join(bonfires)
204 bonfires = bonfires.replace("\n\n","")