-
Notifications
You must be signed in to change notification settings - Fork 3
Tutorial 03 VMCP Responder
In this tutorual we are going to set-up a VM Configuration Point (VMCP) server. This is a server the CernVM WebAPI extension is going to contact in order to obtain the details about the Virtual Machine you are about to launch.
For the very first step we are going to need a webserver. The flask
python mcroframework is the best for this case because with a few lines of code we can have a fully functional web server.
Create a new file called server.py
and paste the following code:
from flask import Flask
from flask import request
app = Flask(__name__)
@app.route("/")
def hello():
return "This is a VMCP server!"
if __name__ == "__main__":
app.run(debug=True)
Save it and run it using python server.py
. Open a web browser and visit http://test.local:5000/.
Congratulations! Your webserver is running!
A Virtual Machine Configuration is a JSON-encoded set of key/value parameters that define the characteristics of the Virtual Machine to be created. Such characteristics include the instance name, the operating system, the ammount of ram to allocate, the ammount of disk to allocate etc.
Let's prepare a dictionary with the configuration of our new VM:
# Machine configuration
MACHINE_CONFIG = {
'name' : 'My first VM',
'secret' : 'pr0t3ct_this',
'userData' : "[amiconfig]\nplugins=cernvm\n[cernvm]\ncontextualization_key=0c41ec2627604bc09457de39e190c24c\n",
'ram' : 128,
'cpus' : 1,
'disk' : 1024,
'flags': 0x31
}
NOTE: If you are curious about the flags
field, can have a look on Appendix.
Then let's create a new route on flask microframework that is going to render that response:
@app.route("/vmcp")
def vmcp_sign():
return json.dumps( MACHINE_CONFIG )
Putting it all together:
import json
from flask import Flask
from flask import request
app = Flask(__name__)
# Machine configuration
MACHINE_CONFIG = {
'name' : 'My first VM',
'secret' : 'pr0t3ct_this',
'userData' : "[amiconfig]\nplugins=cernvm\n[cernvm]\nusers=user:users:user\n",
'ram' : 128,
'cpus' : 1,
'disk' : 1024,
'flags': 0x31
}
@app.route("/vmcp")
def vmcp_sign():
return json.dumps( MACHINE_CONFIG )
@app.route("/")
def hello():
return "This is a VMCP server!"
if __name__ == "__main__":
app.run(debug=True)
In order to form a proper VMCP response you will need to sign the response with your domain's private key. The tutorial files already contain a library for this purpose and a private key for the test.local
domain, so let's use it!
First, we are going to need to import the utility library and instantiate a VMCPSigner class:
from util.vmcp import VMCPSigner
# Create a signer instance
signer = VMCPSigner( "res/test-local.pem" )
Now we can modify the vmcp_sign function in order to actually sign the response:
@app.route("/vmcp")
def vmcp_sign():
return json.dumps( signer.sign( MACHINE_CONFIG, request.args.get('cvm_salt') ) )
Now, if you try and visit http://test.local:5000/vmcp you are going get an exception, because you are missing cvm_salt
parameter. This parameter, along with cvm_hostid
are passed as GET parameters to the VMCP URL.
The cvm_salt
is a random string which takes part to the signing process and is used to prevent replay attacks.
If you want to test your set-up, just pass a random cvm_salt parameter: http://test.local:5000/vmcp?cvm_salt=random
Your code so far should look like this:
import json
from util.vmcp import VMCPSigner
from flask import Flask
from flask import request
app = Flask(__name__)
# Create a signer instance
signer = VMCPSigner( "res/test-local.pem" )
# Machine configuration
MACHINE_CONFIG = {
'name' : 'My first VM',
'secret' : 'pr0t3ct_this',
'userData' : "[amiconfig]\nplugins=cernvm\n[cernvm]\nusers=user:users:user\n",
'ram' : 128,
'cpus' : 1,
'disk' : 1024,
'flags': 0x31
}
@app.route("/vmcp")
def vmcp_sign():
return json.dumps( signer.sign( MACHINE_CONFIG, request.args.get('cvm_salt') ) )
@app.route("/")
def hello():
return "This is a VMCP server!"
if __name__ == "__main__":
app.run(debug=True)