Informatiq (Talk | contribs) (Created page with '= What is IMG = IMG (Image Me Give) is a small python client/server application suite, its sole job is to get a POST'd kickstart file from a user and then run Moblin-Image-Creat…') |
|||
| Line 5: | Line 5: | ||
= Design = | = Design = | ||
* Asynchronous | * Asynchronous | ||
| - | :Fire and forget about it | + | :Fire and forget about it, check back later with the cli client for results |
| - | + | * Queue view with django, | |
| - | + | ||
| - | * Queue view, | + | |
:Show a nice html view of currently running or standby MIC jobs in the queues | :Show a nice html view of currently running or standby MIC jobs in the queues | ||
* Submit/cancel via .ks | * Submit/cancel via .ks | ||
:Upload via a form | :Upload via a form | ||
| - | |||
| - | |||
* No security | * No security | ||
:No https or file filter restrictions :) | :No https or file filter restrictions :) | ||
| Line 19: | Line 15: | ||
== Example workflow == | == Example workflow == | ||
| - | The application consists of two parts, django frontend and the actual image creation application. Both of them are connected via | + | The application consists of two parts, django frontend and the actual image creation application. Both of them are connected via AMQP, RabbitMQ is used as the server. |
So an example workflow: | So an example workflow: | ||
| Line 27: | Line 23: | ||
# When the object is saved, a message is sent via a broker to the image creation app, containing the details for the creation. | # When the object is saved, a message is sent via a broker to the image creation app, containing the details for the creation. | ||
## Image creation commences | ## Image creation commences | ||
| - | ## Virtual machine disk image containing mic2 and kickstarter is engaged (as a | + | ## Virtual machine disk image containing mic2 and kickstarter is engaged (as a kvm overlay image), with ssh access. |
| - | ### When a yaml overlay is received, it is passed via kickstarter and then to | + | ### When a yaml overlay is received, it is passed via kickstarter and then to worker |
| - | ### When a kickstart file is received, it is passed directly to | + | ### When a kickstart file is received, it is passed directly to worker |
| - | ## | + | ## Worker starts up and connects to the virtual machine using ssh and passes the required arguments to mic2. |
| - | ## When mic2 has finished, the virtual machine | + | ## Worker copies image on success from the virtual machine to well-known www-root, if there is an error, only a message about it is sent via AMQP. |
| + | ## When mic2 has finished, the virtual machine is shut down by the worker. | ||
## When image is created, the virtual machine disk image is deleted | ## When image is created, the virtual machine disk image is deleted | ||
| - | + | <!-- | |
= Overlays = | = Overlays = | ||
| Line 101: | Line 98: | ||
- gcc | - gcc | ||
- -google-chrome | - -google-chrome | ||
| - | + | --> | |
= Client = | = Client = | ||
For demonstration see [http://meego.gitorious.org/meego-infrastructure-tools/imger/blobs/master/src/meego_img/client.py client.py] for example client. | For demonstration see [http://meego.gitorious.org/meego-infrastructure-tools/imger/blobs/master/src/meego_img/client.py client.py] for example client. | ||
| + | == Usage == | ||
| + | |||
| + | client.py -p|--poll <message_id> -t|--type <imagetype> -a|--async <kickstart_file.ks> | ||
| + | |||
| + | where: | ||
| + | : -p|--poll <message_id>, poll the AMQP server for messages relating to the id, see -a|--async | ||
| + | : -t|--type <imagetype>, image type, can be of: livecd, liveusb, loop, raw, nand, mrstnand, vdi or vmdk | ||
| + | : -a|--async <kickstart_file.ks>, the kickstart file to submit | ||
| + | |||
| + | = BOSS Client = | ||
| + | |||
| + | See [http://meego.gitorious.org/meego-infrastructure-tools/imger/blobs/master/src/meego_img/boss_client.py boss_client.py] for example BOSS client. | ||
| + | |||
| + | == Usage == | ||
| + | |||
| + | boss_client.py <kickstart.ks> | ||
| - | + | = Django client = | |
=== Views === | === Views === | ||
| - | * submit | + | * submit |
| - | :If this | + | :If this view receives a POST request, it constructs a bound form with the data from POST array. If the form is valid it extracts the data, as specified in the forms section. |
:Applying the overlay is handled in this form, in the following way. | :Applying the overlay is handled in this form, in the following way. | ||
* Get the overlay text from the form field | * Get the overlay text from the form field | ||
| Line 117: | Line 130: | ||
*parse the template configurations.yaml | *parse the template configurations.yaml | ||
**append the overlay list to the platform selected via the form, to the !ExtraPackages element | **append the overlay list to the platform selected via the form, to the !ExtraPackages element | ||
| - | :After the overlay is applied, the resulting YAML template is passed to the kickstarter via a message | + | :After the overlay is applied, the resulting YAML template is passed to the kickstarter via a AMQP message. |
* queue | * queue | ||
| - | :This view is responsible of two things. Firstly it wether there are any | + | :This view is responsible of two things. Firstly it checks wether there are any messages in the "status_queue" message queue, if there are, then it updates the !ImageJob model object (identified by the identification string from the message) to include the ready image URL. |
| - | :Secondly, it checks for possible error messages in " | + | :Secondly, it checks for possible error messages in "status_queue" queue, if there are any, it assigns a special variable to indicate that there has been an error. |
:If no messages are received, it simply redirects to a template with all the !ImageJob model objects. | :If no messages are received, it simply redirects to a template with all the !ImageJob model objects. | ||
* job | * job | ||
| - | :Job view is responsible of providing the information about the log file. The information about the logfile is formed in the server side, such as the file | + | :Job view is responsible of providing the information about the log file. The information about the logfile is formed in the server side, such as the URL to the log file. If there is a URL, it will open the URL and read its contents and return the resulting text to the template. The template renders the log message with a textarea html widget. |
*index | *index | ||
:Index only returns a template in which one can click a link about uploading the image. | :Index only returns a template in which one can click a link about uploading the image. | ||
| Line 129: | Line 142: | ||
=== URLs === | === URLs === | ||
url(r'submit/$', 'meego_img.app.views.submit', name='img-app-submit'), | url(r'submit/$', 'meego_img.app.views.submit', name='img-app-submit'), | ||
| - | url(r'queue/$', 'meego_img.app.views.queue', name='img-app-queue'), | + | url(r'queue/$', 'meego_img.app.views.queue', name='img-app-queue'), |
| - | + | url(r'job/(?P<msgid>\S+)$', 'meego_img.app.views.job', name='img-app-job'), | |
| - | url(r'job/(?P<msgid>\S+)$', 'meego_img.app.views.job', name='img-app-job'), | + | |
| - | + | ||
url(r'images/(?P<msgid>\S+)$', 'meego_img.app.views.download',name='img-app-download'), | url(r'images/(?P<msgid>\S+)$', 'meego_img.app.views.download',name='img-app-download'), | ||
=== Models === | === Models === | ||
| Line 173: | Line 184: | ||
This section documents the server component of IMG. | This section documents the server component of IMG. | ||
| + | |||
== Functionality == | == Functionality == | ||
| Line 207: | Line 219: | ||
* image_queue | * image_queue | ||
| - | :Stores messages related to Moblin Image Creator runtime | + | :Stores messages related to Moblin Image Creator runtime. |
* kickstarter_queue | * kickstarter_queue | ||
| - | :Stores messages related to kickstarter runtime | + | :Stores messages related to kickstarter runtime. |
Queues for exchange "django_result_exchange": | Queues for exchange "django_result_exchange": | ||
| - | * | + | * status_queue |
:Contains messages in the following format (JSON encoded dictionary): | :Contains messages in the following format (JSON encoded dictionary): | ||
| - | ** 'id': the identification string of the original message sent to kickstarter_queue | + | ** 'status': status of the image build, compulsory |
| - | + | ** 'id': the identification string of the original message sent to kickstarter_queue, compulsory | |
| - | + | ** 'url': Contains the URL from which one can download the image | |
| - | + | ** 'log': specifies the log file to read from | |
| - | ** ' | + | ** 'error': any error messages faced |
| - | + | ||
| - | + | = BOSS participant = | |
| - | + | ||
| - | + | See [http://meego.gitorious.org/meego-infrastructure-tools/imger/blobs/master/src/meego_img/participant.py participant.py] for the source code. | |
| - | + | ||
| - | + | More information about BOSS [Infrastructure/BOSS]. | |
= Messages = | = Messages = | ||
Contents |
IMG (Image Me Give) is a small python client/server application suite, its sole job is to get a POST'd kickstart file from a user and then run Moblin-Image-Creator. It is also possible to use kickstarter yaml files to create a tailor-made image or using the default selection of yaml templates.
The application consists of two parts, django frontend and the actual image creation application. Both of them are connected via AMQP, RabbitMQ is used as the server.
So an example workflow:
For demonstration see client.py for example client.
client.py -p|--poll <message_id> -t|--type <imagetype> -a|--async <kickstart_file.ks>
where:
See boss_client.py for example BOSS client.
boss_client.py <kickstart.ks>
url(r'submit/$', 'meego_img.app.views.submit', name='img-app-submit'), url(r'queue/$', 'meego_img.app.views.queue', name='img-app-queue'), url(r'job/(?P<msgid>\S+)$', 'meego_img.app.views.job', name='img-app-job'), url(r'images/(?P<msgid>\S+)$', 'meego_img.app.views.download',name='img-app-download'),
IMG currently has only one model, !ImageJob, here is the Django code for it:
# Create your models here.
class ImageJob(models.Model):
email = models.CharField(max_length=40)
filename = models.CharField(max_length=40)
logfile = models.CharField(max_length=50)
task_id = models.CharField(max_length=30)
imagefile = models.CharField(max_length=50)
created = models.DateTimeField(auto_now_add=True)
error = models.CharField(max_length=500)
type = models.CharField(max_length=10)
status = models.CharField(max_length=30)
def delete(self, *args, **kwargs):
if self.logfile:
if os.path.exists(self.logfile):
os.remove(self.logfile)
os.remove(self.logfile.replace("-log", ""))
print "Removed %s"%self.logfile
super(ImageJob, self).delete(*args, **kwargs)
As can be seen in the delete method, this model cleans up all image creation related files, like the kickstarter file and log file.
Contains the following fields
See image_creator.py for example server.
This section documents the server component of IMG.
'error': Contains the error message of the exception received from the python subprocess call. 'id': identification string of the original message sent to "image_queue" queue 'url': Contains the URL from which one can download the log
'url': Contains the URL from which one can download the image
'id': identification string of the original message sent to "image_queue" queue
Queues for exchange "image_exchange":
Queues for exchange "django_result_exchange":
See participant.py for the source code.
More information about BOSS [Infrastructure/BOSS].
The general message format is JSON encoded dictionary.
To initialize kickstarter, send a JSON formatted message as follows:
{'config':config, 'email':'email', 'imagetype':'imagetype', 'id': id}
where:
To initialize the actual image building, send a JSON formatted message as follows:
{'email':email, 'id':id, 'imagetype':imagetype, 'ksfile':ksfile}
where: