Friday, June 28, 2013

Build a Cloud Paris recap

On June 19th we had a Build a Cloud Day in Paris, 60 of us gathered to learn about Apache CloudStack and ear from CloudStack users, integrators and ecosystem partners. We had four great sponsors that helped make the event possible: iKoula a public cloud provider in Paris, Usharesoft a software provider, Apalia a CloudStack integrator and editor of Amysta a CloudStack usage and metering plugin and OW2 an open source consortium. I finally got all the slides and I embed them in this post for your enjoyment. The day started with an intro about BACD and a presentation of the various talks that we were going to have. I talked about the Apache Software Foundation (ASF) and showed how several Apache projects could be used to build a complete cloud infrastructure.

Ikoula followed with a presentation on how to use CloudStack to build a public cloud. Public clouds are the natural evolution of traditional hosting providers, ikoula offers several cloud services based on a default CloudStack install. With 1,000 servers and approximately 8,000 Virtual machines in the cloud it is a perfect example of a public cloud in production with CloudStack. In the afternoon, Joaqium Dos Santos gave an introductory demo on the CloudStack API and CloudMonkey.

Following a presentation on public cloud, Florent Paillot from INRIA talked about the national continuous integration platform. A built and test system for INRIA researchers. Private cloud used for build and test are a common use case for CloudStack. Florent shared the design and reasoning that went into choosing CloudStack. He also talked about operational details and some issues that he will bring back up to the CloudStack mailing list.

With Public and Private cloud use cases behind us it was time to talk about the software that are available to uses to bring added value and ease of use to their cloud. The first presentation was from UshareSoft, a software that makes image creation and management a breeze. UshareSoft also offers a marketplace ala App Store and a migration service. In the afternoon we had a complete hands-on demo of USharesoft, which boasts a sleek user interface and intuitive image management capabilities.

Activeeon followed just before lunch. Activeeon had already presented at the BACD in Ghent back in January, Brian Amedro the CTO talked about ProActive and its CloudStack Plugin. Proactive is used to manage complex computational workflows in industry such as the financials, pharmaceuticals and video editing. The CloudStack use case was particularly telling: working with a customer they used the CloudStack plugin for video rendering on-demand.

In the fall I had the opportunity to work with a group of students from the Ecole des Mines de Nantes. They developed a CloudStack plugin for BtrCloud, a software that can optimize the placement of virtual machines in the data center. BtrCloud presented the latest development of this plugin, showcasing an embedded user interface and the ability to create various rules (e.g affinity, anti-affinity, spread, pack..) for migration. BtrCloud promises to be very interesting as it could be used for Green IT in the Cloud.

We ended the day with a presentation on cloud usage metering with Amysta. Cloud usage is an internal functionality of CloudStack, which keeps track of all usage in a MySQL database. Amysta extends the core CloudStack metering capability with an embedded interface to create very fine grained usage reports on all resources. Pricing and currency can be set and reports generated in various formats for organizations or individual users.

And that was it in Paris, we will certainly plan another event as everyone was very interested to learn even more. iKoula offered to host a regular CloudStack meet-up, stay tuned for information on that front !

Wednesday, June 26, 2013

CloudStack support in Apache Libcloud

A vote has started on the libcloud dev list for the 0.13 release. The release notes detail all the new features and fixes. I am stoked about this because a few patches that I submitted are included in this release candidate. I patched the CloudStack driver quite a bit to improve the support for Clouds with a basic zone like Exoscale. There is more work to do on this driver including better support for Advanced zone especially for port forwarding, firewall rules and more unit tests. A the CloudStack hackathon last sunday @pst418 submitted a few patches for unit tests and they made it as well into 0.13 RC, terrific.

If you don't know libcloud, it's a python based API wrapper to abstract the various cloud APIs. With libcloud you can create connections to multiple clouds, potentially using different API. At a high level, it is similar to jclouds for JAVA or deltacloud written in ruby. There was already a CloudStack driver but its functionality was limited. If you grab my quickie libcloud shell, you can try to follow this walkthrough of what you can do with libcloud and a CloudStack basic zone. Of course you will need a CloudStack endpoint.

Start the libshell and check what zone you are on:

$ python ./libshell.py 
Hello LibCloud Shell !!
You are running at: https://api.exoscale.ch/compute
>>> conn.list_locations()
[<NodeLocation: id=1128bd56-b4d9-4ac6-a7b9-c715b187ce11, name=CH-GV2, country=AU, driver=CloudStack>]

You might notice a wrong country code, it is hard-coded in libcloud, I need to file a bug for this. Get the list of templates (or images in libcloud speak):

>>> conn.list_images()
[<NodeImage: id=01df77c3-0150-412a-a580-413a50924a18, name=Windows Server 2008 R2 SP1, driver=CloudStack  ...>,
<NodeImage: id=89ee852c-a5f5-4ab9-a311-89f39d133e88, name=Windows Server 2008 R2 SP1, driver=CloudStack ...>,
<NodeImage: id=ccd142ec-83e3-4108-b1c5-8e1fdb353ff9, name=Windows Server 2008 R2 SP1, driver=CloudStack ...>,
<NodeImage: id=f2101a0c-eaf7-4760-a143-0a5c940fd864, name=Windows Server 2008 R2 SP1, driver=CloudStack ...>,
<NodeImage: id=77d32782-6866-43d4-9524-6fe346594d09, name=CentOS 5.5(64-bit) no GUI (KVM), driver=CloudStack ...>,
<NodeImage: id=29cba09f-4569-4bb3-95e7-71f833876e3e, name=Windows Server 2012, driver=CloudStack ...>,
<NodeImage: id=ee241b47-4303-40c8-af58-42ed6bf09f8c, name=Windows Server 2012, driver=CloudStack ...>,
<NodeImage: id=754ea486-d649-49e5-a70e-5e5d458f0df0, name=Windows Server 2012, driver=CloudStack ...>,
<NodeImage: id=0f9f4f49-afc2-4139-b26b-b05a9f51ea74, name=Windows Server 2012, driver=CloudStack ...>,
<NodeImage: id=954752a8-0486-46bb-8e3f-0adb3e01c619, name=Linux CentOS 6.4 64-bit, driver=CloudStack ...<]

I cut the previous output, but there are also Ubuntu and CentOS images on that cloud...You can then list the various instance types or sizes in libcloud speak.

>>> conn.list_sizes()
[<NodeSize: id=71004023-bb72-4a97-b1e9-bc66dfce9470, name=Micro, ram=512 disk=0 bandwidth=0 price=0 driver=CloudStack ...>,
<NodeSize: id=b6cd1ff5-3a2f-4e9d-a4d1-8988c1191fe8, name=Tiny, ram=1024 disk=0 bandwidth=0 price=0 driver=CloudStack ...>,
<NodeSize: id=21624abb-764e-4def-81d7-9fc54b5957fb, name=Small, ram=2048 disk=0 bandwidth=0 price=0 driver=CloudStack ...>,
<NodeSize: id=b6e9d1e8-89fc-4db3-aaa4-9b4c5b1d0844, name=Medium, ram=4096 disk=0 bandwidth=0 price=0 driver=CloudStack ...>,
<NodeSize: id=c6f99499-7f59-4138-9427-a09db13af2bc, name=Large, ram=8182 disk=0 bandwidth=0 price=0 driver=CloudStack ...>,
<NodeSize: id=350dc5ea-fe6d-42ba-b6c0-efb8b75617ad, name=Extra-large, ram=16384 disk=0 bandwidth=0 price=0 driver=CloudStack ...>,
<NodeSize: id=a216b0d1-370f-4e21-a0eb-3dfc6302b564, name=Huge, ram=32184 disk=0 bandwidth=0 price=0 driver=CloudStack ...>]

What I added is the management of ssh key pairs and security groups, you can now list, create and delete both keypairs and security groups, and use those when deploying nodes. (Don't bother trying to do anything with the keys below, I deleted everything.)

>>> conn.ex_list_keypairs() 
[{u'name': u'foobar', u'fingerprint': u'b9:2d:4b:07:db:e7:3e:42:17:11:22:33:44:55:66:77'}]

>>> conn.ex_list_security_groups()
[{u'egressrule': [], u'account': u'foobar@gmail.com', u'domainid': u'ab53d864-6f78-4993-bb28-9b8667b535a1', u'description': u'Default 
Security Group', u'tags': [], u'domain': u'foobar@gmail.com', u'ingressrule': [{u'startport': 22, u'cidr': u'0.0.0.0/0', u'protocol':
u'tcp', u'endport': 22, u'ruleid': u'b83428c0-7f4c-44d1-bc96-4e1720168fdf'}, {u'startport': 80, u'cidr': u'0.0.0.0/0', u'protocol':
u'tcp', u'endport': 80, u'ruleid': u'042124dd-652d-4fa2-8bee-d69973380f21'}], u'id': u'ebfa2339-e9ae-4dcb-b73c-a76cd3fce39e', u'name':
u'default'}, {u'account': u'foobar@gmail.com', u'domainid': u'ab53d864-6f78-4993-bb28-9b8667b535a1', u'description': u'this is a test',
u'domain': u'foobar@gmail.com', u'id': u'b7f5fbad-4244-491f-9547-c91a010e0c9d', u'name': u'toto'}] >>> conn.ex_create_keypair('test') {u'privateKey': u'-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQCAuPufJnbzFkyIUaMymkXwfilA5qS2J9fx2Q3EWNDs1m89FLFq\n19ERjG43ZvRuI/KGwWZwHbhqoqJth7WQYNe
lYCmOUYRaepxTrpU4TGDGuhqMh9D9\
noNMIFx3ktkcTitxkSY/5h/pXqSB2XXURLpZWwZxjEYwWCpWE8i7uVtIR7wIDAQAB\nAoGAOv0Kik9lOVbhsaK/yAO8w039d7l6h+NQaYtPbMhKzg4iofomp9DJBWK2a3sp\
nzoN4s9pTKFPmXC+1gb4sLULD72ENSgyozrPMCJ0tytNa3ebVCCYDvlagEZ83KwGn\nnr2BIRLul1xyHVa+amvTemuxi7OOx0u/0aZ6jPVW9ocPahkCQQDnUACG3Q2p60Mx\
nCttW7Go2wz0BhaI8ibG8rHorhdrFJUrsTI6QrLh340uHCIEAuWUXjYDX2u5MTPBG\njWbL/A/9AkEAjnX8EzO/B/RooFTxhYdxv7D1Dzcx4H59mFzjez6N/mjAHjKL4p66\
nqGFgLa9HMhDPFOs83VetBXcihu1vueffWwJBALQUD2TvAS0wz82FYz8nrITXuE3Q\nCH7Sv8FgEXiCq89hehO+ghrVrIMBPBJzJ2M18iLE8fKaKXzTRRfYC5hwss0CQHY8\
nBdIKCGoZtxwaY7lnCEkIHNtb+9FOKf7iWQpYiJC1b32ghei3xEMrTh+ccYJj4PqD\noigyNC9tCQLi3O92OjECQGYR2z8IDlfnl7G8p7eiyBciuoDyyq5/oJHhkHbkbwzr\
nW0Uun+rEcjRnXbUN8wUQ6FSFrxk2VSajbCBteTOrF24=\n-----END RSA PRIVATE KEY-----\n', u'name': u'test', u'fingerprint': u'43:59:7e:00:16:45:fc:ab:81:55:03:47:12:22:1e:d5'} >>> conn.ex_list_keypairs() [{u'name': u'test', u'fingerprint': u'43:59:7e:00:16:45:fc:ab:81:55:03:47:12:22:1e:d5'}, {u'name': u'foobar',
u'fingerprint': u'b9:2d:4b:07:db:e7:3e:42:17:11:22:33:44:55:66:77'}] >>> conn.ex_delete_keypair('test') u'true' >>> conn.ex_list_keypairs() [{u'name': u'foobar', u'fingerprint': u'b9:2d:4b:07:db:e7:3e:42:17:11:22:33:44:55:66:77'}] >>> conn.ex_create_security_group('heyhey') {u'account': u'runseb@gmail.com', u'domainid': u'ab53d864-6f78-4993-bb28-9b8667b535a1', u'id':
u'77ad73b5-a383-4e13-94be-a38ef9877996', u'domain': u'runseb@gmail.com', u'name': u'heyhey'} >>> conn.ex_list_security_groups() [{u'egressrule': [], u'account': u'foobar@gmail.com', u'domainid': u'ab53d864-6f78-4993-bb28-9b8667b535a1',
u'description': u'Default Security Group', u'tags': [], u'domain': u'foobar@gmail.com', u'ingressrule': [{u'startport': 22, u'cidr':
u'0.0.0.0/0', u'protocol': u'tcp', u'endport': 22, u'ruleid': u'b83428c0-7f4c-44d1-bc96-4e1720168fdf'}, {u'startport': 80, u'cidr': u'
0.0.0.0/0', u'protocol': u'tcp', u'endport': 80, u'ruleid': u'042124dd-652d-4fa2-8bee-d69973380f21'}], u'id': u'ebfa2339-e9ae-4dcb-b73c-a76cd3fce39e',
u'name': u'default'}, {u'account': u'foobar@gmail.com', u'domainid': u'ab53d864-6f78-4993-bb28-9b8667b535a1', u'description':
u'this is a test', u'domain': u'foobar@gmail.com', u'id': u'b7f5fbad-4244-491f-9547-c91a010e0c9d', u'name': u'toto'},
{u'account': u'foobar@gmail.com', u'domainid': u'ab53d864-6f78-4993-bb28-9b8667b535a1', u'id': u'77ad73b5-a383-4e13-94be-a38ef9877996',
u'domain': u'foobar@gmail.com', u'name': u'heyhey'}] >>> conn.ex_delete_security_group('heyhey') u'true' >>> conn.ex_list_security_groups() [{u'egressrule': [], u'account': u'runseb@gmail.com', u'domainid': u'ab53d864-6f78-4993-bb28-9b8667b535a1',
u'description': u'Default Security Group', u'tags': [], u'domain': u'foobar@gmail.com', u'ingressrule': [{u'startport': 22, u'cidr':
u'0.0.0.0/0', u'protocol': u'tcp', u'endport': 22, u'ruleid': u'b83428c0-7f4c-44d1-bc96-4e1720168fdf'}, {u'startport': 80, u'cidr':
u'0.0.0.0/0', u'protocol': u'tcp', u'endport': 80, u'ruleid': u'042124dd-652d-4fa2-8bee-d69973380f21'}], u'id': u'ebfa2339-e9ae-4dcb-b73c-a76cd3fce39e',
u'name': u'default'}, {u'account': u'foobar@gmail.com', u'domainid': u'ab53d864-6f78-4993-bb28-9b8667b535a1',
u'description': u'this is a test', u'domain': u'foobar@gmail.com', u'id': u'b7f5fbad-4244-491f-9547-c91a010e0c9d', u'name': u'toto'}]

With a security group created you can now add an ingress rule:

>>> conn.ex_authorize_security_group_ingress(securitygroupname='toto',protocol='TCP',cidrlist='0.0.0.0./0',
startport=99) {u'egressrule': [], u'account': u'runseb@gmail.com', u'domainid': u'ab53d864-6f78-4993-bb28-9b8667b535a1',
u'description': u'this is a test', u'domain': u'runseb@gmail.com', u'ingressrule': [{u'startport': 99, u'cidr': u'0.0.0.0./0',
u'protocol': u'tcp', u'endport': 99, u'ruleid': u'a13a21f9-1709-431f-9c7d-e1a2c2caacdd'}],
u'id': u'b7f5fbad-4244-491f-9547-c91a010e0c9d', u'name': u'toto'} >>> conn.ex_list_security_groups() [{u'egressrule': [], u'account': u'runseb@gmail.com', u'domainid': u'ab53d864-6f78-4993-bb28-9b8667b535a1',
u'description': u'Default Security Group', u'tags': [], u'domain': u'runseb@gmail.com', u'ingressrule': [{u'startport': 22, u'cidr':
u'0.0.0.0/0', u'protocol': u'tcp', u'endport': 22, u'ruleid': u'b83428c0-7f4c-44d1-bc96-4e1720168fdf'}, {u'startport': 80, u'cidr':
u'0.0.0.0/0', u'protocol': u'tcp', u'endport': 80, u'ruleid': u'042124dd-652d-4fa2-8bee-d69973380f21'}], u'id':
u'ebfa2339-e9ae-4dcb-b73c-a76cd3fce39e', u'name': u'default'}, {u'egressrule': [], u'account': u'runseb@gmail.com', u'domainid':
u'ab53d864-6f78-4993-bb28-9b8667b535a1', u'description': u'this is a test', u'tags': [], u'domain': u'runseb@gmail.com', u'ingressrule':
[{u'startport': 99, u'cidr': u'0.0.0.0./0', u'protocol': u'tcp', u'endport': 99, u'ruleid': u'a13a21f9-1709-431f-9c7d-e1a2c2caacdd'}],
u'id': u'b7f5fbad-4244-491f-9547-c91a010e0c9d', u'name': u'toto'}]

Great, keypair and security group work fine. Now let's do the basics of starting an instance and let's test the suspend and resume which was not in the Driver until now. Nothing earth shattering but it's an improvement.

>>> size=conn.list_sizes()
>>> image=conn.list_images()

>>> n=conn.create_node(name='yoyo',size=size[0],image=image[0])

>>> n.ex_stop()
u'Stopped'
>>> n.ex_start()
u'Running'

And that's it for now, CloudStack support is getting better, there is still tons of work to do: improve the advanced zone support, check the load-balancer and storage support, add unit-tests and new CloudStack features like auto-scaling. Carry on !!!!

Build a Cloud Day Amsterdam recap

On June 13th we had a Build a Cloud Day workshop in Schuberg Phillis offices in Amsterdam. We had a good crowd with a little over 30 people gathering to learn about CloudStack, its use cases, monitoring, PaaS, SDN and client tools. We had good fun and it was a very productive meeting.

We started off with a talk from Arjan Eriks from Schuberg Phillis, Arjan gave us a terrific overview of the Schuberg's culture and how the Cloud and DevOps processes naturally appeared within Schuberg. Their team oriented approach to customer support evolved to using CloudStack as their core IT solution to provide an agile infrastructure that meets the need of their customers. Adding to the Cloud infrastructure, a DevOps culture permeated Schuberg even before DevOps really existed. His slides below will give you a good idea of how a company moves to the Cloud and uses agile methods to make customers and employees "happy".

Following Arjan we had the chance to hear from Julien Pivoto (@roidelapluie) of Inuits an IT consulting company that helps its customers adopt open source solutions and embrace a DevOps culture. Julien presented the suite of open source monitoring tools that can be used to monitor a Cloud infrastructure at scale. From logstash, elasticsearch and Kibana, to collectd, graphite and riemann. Julien did a great job introducing all these tools and explaining how they stitch together to help automation of a Cloud infrastructure.

Hugo Trippaers (@Spark404) then gave us a very practical talk about SDN (Software Defined Networking). Hugo has developed the Nicira NVP integraton in Apache CloudStack and manages the Cloud at Schuberg Phillis. He reviewed all the SDN support in CloudStack (e.g Nicira, native OVS manager, Big Switch, Midonet) and then dove into a Nicira use case. This really brought home the fact that SDN is not a fiction but a reality.

After these first talks about a company's view of Cloud and DevOps, a review of key monitoring tools and SDN solutions in CloudStack, Giles Sirett from Shapeblue presented us with several CloudStack use cases. Shapeblue is a CloudStack integrator in the UK with offices in India, US and Brazil. Giles insider's look on how company choose a Cloud solution and how CloudStack empowers them is unique. This was a very energizing talk showing use that CloudStack is gaining momentum and being adopted all over the world.

CloudStack is a IaaS solution, but once you have built your IaaS you need to focus on application delivery. Arash Kaffamanesh from Cloudssky talked to us about PaaS and showed a few demos on Appscale and Stackato integration with CloudStack. PaaS integration is set to become a hot topic within the next year and Arash lightning talk certainly set the stage. I know of folks working on better CloudStack support in Cloudfoundry/BOSH as well, so expect to see PaaS/CloudStack integration soon.

After these relatively strategic talk we went back to developer tools with Sander Botman. Sander is currently taking the lead in maintaing the Knife CloudStack plugin. Knife is the command line utility from Opscode, it is a great tool to manage your Chef repository. Written in ruby it is highly customizable and has numerous plugins. Sander demoed the knife-cloudstack plugin which let's you provision instances on your CloudStack based cloud and automatically boostrap these instances using chef recipes. I have used knife-cs recently and even submitted a few patches. It is a terrific tool, easy to use with lots of options. If you are looking for a tool to easily provision, configure and manage instances in your cloud, this is it.

Finally, I wrapped up the talks with demos about several CloudStack clients and tools. I have been testing lots of tools lately to prepare content for CloudStack University. I focused on Apache tools form the ASF such as libcloud and jclouds which just entered the incubator. I also looked at higher level wrappers like Apache whirr to create hadoop-clusters on demand. The slides below are still a work in progress and I will put up screencasts up really soon, Stay tuned.

To end the day, we had a few beers, before heading out to the DevOps days pre-conference party. A few folks sneaked out before we took the picture but we all left energized, having learned a ton. We all look forward to the CloudStack conference November 20-22nd in Amsterdam. Should be a blast.

Monday, May 27, 2013

Exoscale, a Swiss Cloud Provider with CloudStack

Over the last couple weeks I have been using exoscale, a swiss public cloud provider based on CloudStack. They just launched after a beta testing phase that I had the chance to be part of. Their offering is primarily aimed at developers. The folks at Exoscale were kind enough to give me couple "gift cards" during the CloudStack Geneva meetup and I was able to get going. Together with PCExtreme, Leaseweb, and iKoula they are one more European public cloud provider in production with Apache CloudStack that I know of.


Their cloud is almost straightforward: two data centers in Geneva and Vernier, with hardware hosted by Equinix. They run Apache CloudStack 4.0.2, the latest release and use KVM hypervisors on Ubuntu based servers. One customization that they made and that I am aware of is that they patched CloudStack to output logs using logstash and use Kibana for visuzalization. They offer CentOS 6.4 and Ubuntu 12.04/13.04 64 bit templates with instance types from 512MB with 1 core to 32 GB with 8 cores. Their development and operations team is relatively small for such an offering but they are backed by the Veltigroup a leading IT provider in Switzerland, which gives them a 20 person team for support. Their developers are seasoned IT infrastructure enthusiasts who participate in the DevOps, openBSD, Clojure and Pallet community. The lead developer, Pierre-Yves Ritschard, formerly with paper.li, recently participated in DevOps Days Paris and has contributed a Clojure client to CloudStack: clostack. They are embracing open source, not only by using it, but also by contributing to the various communities that make up the foundation of Cloud services.

While CloudStack comes with a powerful and efficient Web UI, exoscale decided to create their own UI and integrate it with a ticketing, monitoring and billing system that they developed. It reinforces the fact the CloudStack API is extremely rich and that the default UI was actually designed as a proof of concept rather than something that all users should use. The UI will please developers by its simplicity and straigthforward ease of use. From talking to them, I know they they will soon open source the python client they developed to build the UI backend. Pierre Yves told me it resembled a little bit my toy UI that uses Flask and builds a REST wrapper on top of the CloudStack API. See a snapshot of an instance view below:

They envision an entirely public cloud, meaning that all their instances are on the public network (nb: They also have a premium service for the enterprise with secure VPN access). They use a CloudStack basic zone with security groups ala EC2. Users can get VNC access and of course ssh access to the instance using ssh keys created via the console. Since it is still in beta-testing they have currently turned off some of the features like snapshotting. These feature limitations are well documented and in their roadmap for future releases of their Cloud services. In the meantime they are also working on high level services like Jenkins continuous infrastructure services and most probably big data services. The Big Data service is just a guess on my part but would make sense considering Pierre-Yes involvement with Pallet and a recent demo he did at Eurocloud.

I have used exoscale a lot in those last two weeks and I am extremely pleased with it. It is actually becoming my favorite testbed. The UI is great as I mentioned, but all the CloudStack clients also work (of course :) ), CloudMonkey is easily setup to talk to their endpoint, I submitted patches to libcloud last week and you can now use with exoscale. I even contributed a CloudStack driver for SaltStack (an alternative to Chef and Puppet) based on testing with exoscale. Right away I felt comfortable with exoscale and even gave a lecture at HEPIA where I put 7 students on it in 20 minutes. If you want to learn more, Exoscale will be at Build a Cloud Day Paris on June 19th.

So here is the catchphrase of the blog: Exoscale, it's simple and it works

Thursday, May 23, 2013

The LinuxTag Hack

What do you do when you go to LinuxTag the premier Open Source conference in Berlin Germany ? You give a talk, you hand out tee-shirts at the CloudStack booth, you explain Cloud computing and you hack a CloudStack driver for SaltStack while patching libcloud.

The talk: Talking about Clouds is nice and all, but after many years and many talks, I shamelessly admit that it gets a little old. So lately I have been working on BigData, both as a backend to CloudStack (think Ceph, Riack CS, Gluster) and as a workload to a cloud. I am talking about using Apache Whirr or Apache Provisionr incubating to deploy "one-click" hadoop clusters on public clouds. It is a long story that I will keep for another post as I am trying to write this before going to bed. but check out the slides and keep an eye on pallet and exoscale.

The booth: An open source booth is ..well a booth. I came with my pop-up banner, table cloth, tee-shirts, post-cards, USB stick/bottle openers, it feels a little bit like a traveling sales man, not that I would know but I imagine it like this. I have to explain that the 2 and 3 XL shirts will shrink quite a bit and will fit perfectly people's M or L frames. Then I point at the banner to showcase the magnificient CloudStack UI, I explain that there is an API server behind it. Sometimes I launch devcloud and do a live demo to bring them to their knees, sometimes I have to ask for help on IRC to answer a question, and sometimes a german developer wants to trade a tee-shirt against illegal substances not to be named. Life in the fastlane let me tell you. But that's what it's like to build a community, it is very much an evangelization process.

The hack: Then there is the hack, going to an open source conference without writing code would be a sin. The OSS gods decided to put me next to Tom Hatch the CTO of Saltstack. Tom is a funny guy with a deep voice and madenning Python skills. Saltstack is an alternative to Chef and Puppet which are written in this foreign language Ruby. It does configuration management, remote execution, cloud deployments and tons of other things. I was also happily surprised to find 300 folks on IRC, very chatty folks I might add. Anyway, Saltstack was not going to go anywhere because they did not have a CloudStack driver. EC2 yes, Rackspace yes, Joyent yes, OpenStack yes...but no CloudStack. I had to do something about it. A quick git clone and a RTFM later I was on my way, thanks to my new best friend exoscale, a Swiss public cloud provider (based on CloudStack off course) who gave me 50 Francs worth of Cloud Brownies I could test everything live.

I did not want to run any silly master on my laptop, behind crazy NAT non sense, so I used Salt-cloud, I copied the linode driver and started hacking it. It uses libcloud which thankfully I had looked at just couple weeks ago while writing a bit of CloudStack doc. There was a few issues with the libcloud driver so I opened couple bugs there and committed to patches to fix my own bugs, isn't it nice ? Grant it there are not big bugs, but bugs they are, 329 and 330 to be exact.

I got it working and finished it tonight which explains my excitement. I forked their repo on git and made two pull requests that got merged right away. Let's get down to it, shall we. You need two configuration file: cloud and profile

Your cloud conf defines your Cloud Provider and which driver it uses, that's where I define exoscale, my keys etc...

providers:
  exoscale:
    apikey:  
    secretkey: 
    host: api.exoscale.ch
    path: /compute
    securitygroup: default
    user: root
    private_key: 
    provider: cloudstack

Your profile conf defines the instance type that you are going to use, it's a combination of the image, the service offerings and the keys used to access the instance that it will create...

ubuntu-exoscale:
    provider: exoscale
    image: 1d16c78d-268f-47d0-be0c-b80d31e765d2 
    size: b6cd1ff5-3a2f-4e9d-a4d1-8988c1191fe8 
    ssh_interface: public
    ssh_username: root
    keypair: exoscale

With this you can know list-location, list-sizes, list-images:

salt-cloud --list-locations exoscale
Password:
[INFO    ] Configuration file path: /Users/sebastiengoasguen/.saltcloud/cloud
[INFO    ] salt-cloud starting
cloudstack
  CH-GV2
    country: AU
    id: 1128bd56-b4d9-4ac6-a7b9-c715b187ce11

salt-cloud --list-sizes exoscale
Password:
[INFO    ] Configuration file path: /Users/sebastiengoasguen/.saltcloud/cloud
[INFO    ] salt-cloud starting
cloudstack
  Extra-large
    bandwidth: 0
    disk: 0
    id: 350dc5ea-fe6d-42ba-b6c0-efb8b75617ad
    price: 0
    ram: 16384
    uuid: edb4cd4ae14bbf152d451b30c4b417ab095a5bfe
...snip...

salt-cloud --list-images exoscale
[INFO    ] Configuration file path: /Users/sebastiengoasguen/.saltcloud/cloud
[INFO    ] salt-cloud starting
cloudstack
  CentOS 5.5(64-bit) no GUI (KVM)
    extra:
      format: QCOW2
      hypervisor: KVM
      os: CentOS 5.5 (64-bit)
    id: 77d32782-6866-43d4-9524-6fe346594d09
    uuid: 2fb9ae4b32b4ea5eafd3341166cf948cfe24aa7f
...snip...
And finally of course:
salt-cloud -p ubuntu-exoscale lll
This will start the instance on the cloud, do key based ssh access to it and start bootstrapping saltstack. Tomorrow I will check out their actual configuration management scheme, launch couple minions, hoping to create a monogd cluster or even a hadoop cluster. Before you ask, lll is the name you give to an instance when you get tired.

The caveat to all of this is that my patches to libcloud need to be accepted before the CloudStack SaltStack driver is usable. Enjoy ! Signing off. Busy day: Talk, booth, hack

CloudStack European Events this Summer

The summer is going to be full with CloudStack events and talks in Europe.

Choose your event, let's meet, brainstorm and build a great community

Friday, May 17, 2013

CloudStack University

At Apache CloudStack we recently started an initiative to organize our content into learning modules. We call this initiative CloudStack University. Everyone is invited to participate by contributing content (slides and screencasts), suggesting new learning modules that are needed and even creating exercises and assignments. School fun ! As we were discussing the initiative on the mailing list we started by looking at our existing content: slideshares, youtube videos and thought about organizing them into a CloudStack 101 course. This is still a work in progress that requires everyones participation to make it a great resource.

In the meantime I have been putting all my CloudStack content on slideshare and I wanted to provide a narrated version of these slides together with hands-on demo to show folks how to do a few things with CloudStack specifically but also related Cloud and OSS tips and tricks. Here comes the CloudStack university screencasts. I will add more of them as I go along and receive requests from the community (reach out on twitter @sebgoa and tell me what you want to see). I wanted to give you a preview of what this looks like. To create a self-paced learning module, I decided to create slide decks that people can download from slideshare and cross-post the corresponding screencasts (for most of them at least) on youtube. People can choose a particular topic, or take the entire series. The idea is that at the end of watching all the screencasts and reading the material people graduate from CloudStack University.

Certainly one can imagine how this could evolve into a full fledge training and certification program. I do plan to create a final exam once I am done with a consistent set of modules :) In this post I wanted to introduce you to some of the first modules I created. I welcome all feedback and suggestions to improve them. Reach out to me on twitter (@sebgoa) or contribute your own modules via the wiki and the mailing lists.

To get started, I show you below the screencast of testing the Apache CloudStack (ACS) 4.0.2 testing procedure. We used this basic procedure as a smoke test for the release and as way to vote on a release. There is far more QA going on for a release, this is just a basic testing to vote on the release. This is definitely geared towards developers, I plan to create a more end-user version of an introduction to CloudStack.

Once you have been introduced to ACS with this testing procedure you can learn the API. CloudStack has a native API as well as an EC2 compatible interface. The following screencasts and slides dives into the ACS API, showing how to do unauthenticated and authenticated calls, create a signature, it finishes with a discussion on REST and nice exercise.

Learning the API and the details of how to create a call by hand is a very nice skill to have. CloudStack has 16 clients on github in various languages, these clients make it extremely easy to use the CloudStack API. However ACS comes with a terrific interactive shell: CloudMonkey. The following module shows you how to install CloudMonkey and how to use it to manage your ACS backed cloud. If you followed the testing procedure, you can use CloudMonkey with your local CloudStack and explore the API.

If you want to participate in the development of CloudStack you can contribute in many different ways, but definitely modifying the source to include new features, fix bugs and add documentation are some of the basic contributions. The following module gives you an introduction to Git the version control system used by ACS. This is aimed at beginners and starts with a demo of gist on github, it then shows a walkthrough of the CloudStack git repo, looks at remote feature branches and finishes with the workflow to create a patch and submit for review.

At ACS we put great care in making sure that everyone in the world can use our software and that means use the UI in their own language and read the documentation in their own language. Translation is a tedious work but very much appreciated by non english speaking users and developers. In this module we show you how to contribute to the translation of CloudStack UI and docs using the Transifex service. We are proud to have over 30 translators who allow us to support the CloudStack UI in 10 languages and have documentation almost complete in 5 languages.

As a final note, Apache Software Foundation is a mentoring organization in the 2013 Google Summer of code. As such CloudStack is participating in GSoC, we are currently reviewing proposals from students and are eager to see the program started. I embed a deck that introduced the various projects we proposed. Stay tuned to learn more about which ones got awarded, notification on May 27th. And remember to keep an eye out for CloudStack University, a great resource for Cloud training.

Monday, May 06, 2013

Update on Apache CloudStack Community Analysis

Since my last post on the analysis of the CloudStack community, we have graduated and became a top-level project. It's about time to give an update on what can be seen as a metric of the health of our community.

All the data presented is based on the analysis of the mailing lists, the data is publicly accessible, I have used it previously, just when we graduated March 22nd, in January and back in November when I did some social network analysis. This study was inspired by John Jiang, now working at Eucalyptus, you can read his analysis, note that he moved it to the Eucalyptus website.

Methodology: As explained in previous posts, a Contributor is considered as someone who sent an email to one of the CloudStack mailing lists. This is not to be confused with a Committer which at the ASF is meant to represent someone with write access to the code. Not all code contributors have write access. I identify Companies as the email domain used by the Contributors. This is because Contributors are none-affiliated in the ASF. Obviously it has some limitations as email domains such as gmail.com can represent different companies. All emails are loaded in a mongodb database and queries are performed to extract the plots that you will see below. We currently have seven mailing lists of varying traffic: announce, users, users-cn, dev, marketing, commits, issues. Note that all JIRA emails are now sent to the issues list. Subscription to these lists and number of messages last month is as follows:

* dev@ 609 subs / ~2600 msgs in Apr
* users@ 782 subs / ~800 msgs in Apr
* issues@ 109 subs / ~2400 msgs in Apr
* commits@ 166 subs / ~3300 msgs in Apr
* marketing@ 85 subs / ~260 msg in Apr
* users-cn@ ~300 subs / ~260 msgs in Apr

Contributors: The plots below show the number of contributors per month since we became an ASF project as well as an accumulation to date. Comparison with traffic prior to joining ASF can be seen in the previous posts. The number of monthly contributors in dev is reaching 225 , while the number of monthly contributors in users is reaching 175. Most notable is that the number of contributors in the users list seem to be closing on the number of contributors in dev. It may indicate a stabilization of the number of developers and an increase in the user base. The accumulation on both lists is now over 500. A comparison of both contributor sets gives us an estimate of 806 for the entire CloudStack community. Of course this does not include people who may only participate in the marketing or announce list, but they are much lower traffic lists. It also does not include participants in the Chinese user lists. This will be in the next post hopefully. From the subscription data listed above you can also see that we have roughly a 30% activity ratio, meaning that 1/3 of the subscribers actually send emails to the lists. Difficult to know if this is a good or bad number, one would need to compare with other ASF projects.

Companies: The plots below show the number of companies contributing on the dev and users lists as well as an accumulation to date. Similarly to the monthly contributor count we are seeing a faster diversification on the users list. This shows that the users list is adding more companies faster than the dev list (~80 and ~60 per month respectively). The accumulation has reached ~230 on the users list and ~190 on the dev list, for a combined 319 total.

Commits and Marketing: The commits list represents the number of committers than modify the code. These committers often apply patches submitted by other contributors without write access to the code. Therefore the plots should not be seen as the total number of code contributors. The plot below shows an increase in the number of Committers just shy of 40. The marketing list is a new list that deals with event planning, its trend is not yet established but the data shows between 50 and 30 contributors per month.

Social Networks: The following graphs shows social networks of the dev and users list. They are aimed at identifying who is most central to the community. It can be used to identify great contributors that should be recognized and be invited to become an Apache committer. Ultimately I want to use it to build a topic based network, so that people searching for a particular subject know who to talk to. I plan to build an interface that would use keywords to dynamically build these graphs and identify the people who contribute to that topic the most. The graphs show the networks for the last four months. Our new Apache CloudStack vice-president Chip Childers is clearly the most central node in the dev list and Ahmad Emneina is the most central contributor on the users list. The size of the nodes is proportional to their centrality and the thickness of the edges shows the strength of the connection between two nodes. Several nodes (contributors) have been filtered to render a readable picture.

Finally, it is important to note that some contributors are not active on the mailing lists. Even though this is an ASF mantra. Specifically we have engaged in a very active translation effort to bring CloudStack to all countries worldwide. Our translation team has 32 members as off the last count. All translation is handled via transifex. I am also working on git analysis to show better information on commits and I pointed out to John Jiang that he used the wrong repository in his latest study. Stay tuned.

Monday, April 29, 2013

How I look at Citrix...

I am closing in on my first year with Citrix working in the community team of Apache CloudStack, it's about time to describe how I look at Citrix and why I decided to leave a +10 year career in academia behind to work on Open Source...at Citrix. Disclaimer: if you don't want to read about Citrix products, stop right there.

Prior to joining Citrix I only knew it as the company that "brings windows to unix" delivering applications through an equivalent of remote desktop. It's a very unsavory and unfair summary at best and the XenDesktop folks will hate me for it :). What I quickly discovered is that Citrix has embraced the Cloud trying to deliver applications "anywhere, to anyone on any device", it is more than talk as I realized by going through the product list. This was especially intriguing to me because I did not understand why Citrix was getting into the Cloud Infrastructure as a Service (IaaS) layer area by acquiring cloud.com. IaaS software is more the purview of data centers vendors and Citrix struck me as a "top of the stack" company.

To understand why I think Citrix is a true Cloud company you need to get back to the Cloud definition that most of us refer to these days. The NIST definition, it defines Cloud as "...a model for enabling ubiquitous on-demand network access to a shared pool of network resources...that can rapidly be provisioned and released with minimal management effort or service provider interaction " it is the coming of age of utility computing where anyone can access any computing service at anytime from anywhere. Virtualization has been a key enabler of Cloud in the data center and the IaaS layer (or Fabric layer) has become the most mature of the Cloud layers. With Citrix acquiring Cloud.com and donating CloudStack to the Apache Software Foundation (ASF) it told me that Citrix was catching up and complementing its portfolio of products. What I did not expect is to realize that Citrix already had the other pieces of the Cloud puzzle building a suite of products that would enable on-demand/scalable network access to applications autonomically, in short: an app-focused cloud middleware.

At the fabric layer, resource sharing deals with computer, network and storage services. Server virtualization is a key component of IaaS and with XenServer Citrix has the leading hypervisor of the Cloud. To share compute resources, and manage farms of XenServer an orchestrator is needed. That's where CloudPlatform (commercial offering of Apache CloudStack) fits in. CloudPlatform orchestrates compute services and leverages existing storage and networking solutions. But here comes NetScaler, the networking piece, load-balancer, application firewall, branch repeater and cloud connector (via GRE tunnels, IPsec and so on). In storage, Sharefile is there. Unfortunately it is not an enterprise data center storage solution like today's large scale object store or traditional NAS solution but more of a DropBox equivalent (again not doing it justice) which includes corporate data governance.

At the Platform layer or PaaS, Citrix deals more with brokering and management of applications than a PaaS like Microsoft Azure or Google App Engine. CloudPortal is set to become a true Cloud broker offering a marketplace of applications, usage metering and billing making use of enterprise IaaS solutions to provision the applications in the datacenter. XenDesktop, XenApp and VDI-in-a-box are some of the solutions that CloudPlatform can broker. This will bring the traditional Citrix business to the Cloud (i.e Avalon project), providing on-demand, scalable, metered IT services.

At the SaaS layer, Citrix provides true collaboration services with it's GoTo* suite and Podio a social/collaborative platform. Surely these will soon be bundled in CloudPlatform for on-demand access. The nature of these apps speak to Citrix commitment to Clouds and a new way of working "anywhere, with anyone on any device" as they empower remote workers. And despite Yahoo's recent announcement about remote working I am very thankful for these apps and for Citrix walking the talk. To keep enabling mobility Citrix also offers additional middleware which I place in this SaaS layer even though they are not end-user application. XenMobileMDM and CloudGateway solve the problem of access management to application and data from the many devices that are now part of an enterprise IT.

Missing Pieces: This short mapping of Citrix products to the three basic layers of the Cloud highlights couple missing pieces. I am listing them here but I have no visibility and Citrix acquisition strategy so don't read anything else into it :). While Citrix has now a strong offering at the IaaS layer with XenServer, CloudPlatform (based on Apache CloudStack) and NetScaler. It does lack a true Cloud data center storage solution that would open the door to the Big Data market. Sharefile is more tailored for the individual end-user within the enterprise. Maybe packaging Apache Hadoop could fill this gap. In any case Citrix has strategic partnerships with NetApp and EMC as well as an innovative partner InkTank which is behind Ceph. At the PaaS layer, CloudPlatform is really a broker between app consumers and the cloud backends. A PaaS for application developers would be an interesting addition, even though these markets are still in the "trigger". A partnership with EMC on CloudFoundry and RedHat on OpenShift focused on integration with CloudStack/CloudPlatform would be interesting. I might also complement the middleware systems with a Data Analytics solution to mine one's data center and optimize application delivery, but that's my research hat thinking. The SaaS is a huge market and the goal is not to cover it all. I don't see any glaring gaps there, what strikes me the most at this layer is that the type of device we use will evolve quickly (e.g Google Glass), if one day people show up to work with "Glasses" what will Citrix Receiver be on Glass ?

Open Source: With this strong vision of Clouds, Citrix seemed perfect for me. What really made me accept the challenge of a new job was that Citrix open sourced CloudPlatform, donating it to the Apache Software Foundation. I had been an Open Source consumer (mostly) for a long time and it seemed right to get on the producer side. This was a true departure from its Microsoft ties, first by acquiring a data center software but second by reaching out to the Linux community. After the Xen Project this move spoke volume to me and was at the same time intriguing. Citrix has now stepped its Open Source efforts even more, putting the Xen Project under the stewardship of the Linux Foundation and being part of the OpenDayLight Software Defined Networking (SDN) consortium. There again IaaS is leading the way. I don't know yet what's in store for the other layers of the Cloud at Citrix, but if the recent Open Source activities are any signs, we can expect to see some Open Sourcing (in various forms: full software, API, community edition etc) at the other layers. This will further improve Citrix's reputation in the OSS community and help create an ecosystem around the terrific portfolio that we already have. Open Sourcing is key to innovation and we want Citrix to be a leading innovator of the Cloud.

In short, there is more to Clouds than virtual machine management and Citrix tackles the end-to-end cloud spectrum reaching out to the dream of computing as a utility in a mobile world.

Monday, April 15, 2013

To REST or not To REST

I wish I could write like Shakespeare but since I don't you are left with this blog about Representational State Transfer (REST) and specifically a discussion on whether the CloudStack API is a REST API or not. The short answer is that the CloudStack API is RESTlike but not RESTfull since it is only based on the GET method. Being an http based API that can return JSON does not make it a RESTfull API. This should not be seen as negative criticism but just a clarification.

A few words first about the CloudStack API and a few pointers. It is very extensive, from user creation, vm management to firewall configuration and more advanced networking features. Github has lots of clients written by the community and I am sure you can find your favorite language in there. The Developer Guide explains in details how to make requests. With CloudMonkey interacting with the API has become even easier. It is a terrific way to learn the API and check the required parameters of each call. Coupled with devcloud you can have a fully functional local CloudStack testbed.

To explore the API, I often also look at the GUI and see how the API calls are made. To do this, I access the UI in Firefox and launch Firebug console. I can then see the calls that I am interested in and specifically check the parameters/headers etc or the http call being made.

REST is known as an architectural style and to put it in french-english it is basically a way to design your API to create a web service that only uses the HTTP methods to manipulate the state of web resources. In my opinion it was really a response to the complexity of the SOAP based web services and the many standards that came out. REST really took off with Web 2.0 and was seen as a way to create easy to use web services. I recently found a few articles by Luis Rei and they clearly explain how to design a REST web service as well as implement on with Flask a lightweight python based web framework.

Looking closely at the CloudStack API we see that it uses http, can return JSON objects but only uses the GET method of HTTP. As such it is really a Query API that we can call RESTLike but not RESTfull similarly to the Amazon AWS EC2 Query API.

To illustrate this point I decided to write a REST wrapper on top of the CloudStack API. This was really the reason behind my CloudStack Silly Tuesday Hack. The actual usefulness of it is still questionable :) it would be better to re-write the CloudStack API into a REST native API. That being said "Cloud wrappers" like jclouds/deltacloud have adopted a stance where they expose an API on top of existing IaaS APIs. So who knows it may be useful.

First I wanted to be able to make http calls via curl and use the default GET based CloudStack API, then I wanted to make it more RESTFull. I decided to use Flask because it has a clean way to define web routes and specify the HTTP method being used. To do all of this I used DevCloud as mentioned above and I was checking all my calls with CloudMonkey. To make simple GET calls via curl and avoid constructing the signature of the calls, I took the requester.py file from CloudMonkey and imported it in my Flask application, checkout the gist for the entire code. Below is a sample "route". In this example we only consider user management.

@app.route('/list')
def list():
    print request.query_string
    res={}
    for key in request.args.iterkeys():
        res[key]=request.args.get(key)
    print res
    response, error = requester.make_request('listUsers',res,None,host,port,apikey,secretkey,protocol,path)
    return response

An http GET to http://localhost:5000/list will be routed to the list() function. The query parameters will be parsed and stored in a dictionary which in turn will be given to listUsers from CloudStack. This is where the silliness lies. A GET that does a GET. Using curl we can easily call this method:

curl -X GET -G 'http://localhost:5000/list'
{ "listusersresponse" : { "count":4 ,"user" : [  {"id":"7ed6d5da-93b2-4545-a502-23d20b48ef2a","username":"admin","firstname":"admin","lastname":"cloud","created":"2012-07-05T12:18:27-0700","state":"enabled","account":"admin","accounttype":1,"domainid":"8a111e58-e155-4482-93ce-84efff3c7c77","domain":"ROOT","apikey":"plgWJfZK4gyS3mOMTVmjUVg-X-jlWlnfaUJ9GAbBbf9EdM-kAYMmAiLqzzq1ElZLYq_u38zCm0bewzGUdP66mg","secretkey":"VDaACYb0LV9eNjTetIOElcVQkvJck_J_QljX_FcHRj87ZKiy0z0ty0ZsYBkoXkY9b7eq1EhwJaw7FF3akA3KBQ","accountid":"7548ac03-af1d-4c1c-9064-2f3e2c0eda0d"}, {"id":"1fea6418-5576-4989-a21e-4790787bbee3","username":"runseb","firstname":"sebgoa","lastname":"goa","email":"joe@smith.com","created":"2013-04-10T16:52:06-0700","state":"enabled","account":"admin","accounttype":1,"domainid":"8a111e58-e155-4482-93ce-84efff3c7c77","domain":"ROOT","apikey":"Xhsb3MewjJQaXXMszRcLvQI9_NPy_UcbDj1QXikkVbDC9MDSPwWdtZ1bUY1H7JBEYTtDDLY3yuchCeW778GkBA","secretkey":"gIsgmi8C5YwxMHjX5o51pSe0kqs6JnKriw0jJBLceY5bgnfzKjL4aM6ctJX-i1ddQIHJLbLJDK9MRzsKk6xZ_w","accountid":"7548ac03-af1d-4c1c-9064-2f3e2c0eda0d"}, {"id":"b3b60a8d-df6f-4ce6-a6f9-6194907457a5","username":"john","firstname":"sebgoa","lastname":"goa","email":"runseb@gmail.com","created":"2013-04-12T05:09:10-0700","state":"enabled","account":"admin","accounttype":1,"domainid":"8a111e58-e155-4482-93ce-84efff3c7c77","domain":"ROOT","accountid":"7548ac03-af1d-4c1c-9064-2f3e2c0eda0d"}, {"id":"62d866e4-da97-46c2-a3e1-10faf6197c73","username":"titi","firstname":"www","lastname":"rr","email":"joe@smith.com","created":"2013-04-15T06:21:59-0700","state":"enabled","account":"admin","accounttype":1,"domainid":"8a111e58-e155-4482-93ce-84efff3c7c77","domain":"ROOT","accountid":"7548ac03-af1d-4c1c-9064-2f3e2c0eda0d"} ] } }

In the response we see the list of all the users in the system. The same list route would also work if we were to pass the id of a single user:

curl -X GET -G 'http://localhost:5000/list' -d id=7ed6d5da-93b2-4545-a502-23d20b48ef2a
{ "listusersresponse" : { "count":1 ,"user" : [  {"id":"7ed6d5da-93b2-4545-a502-23d20b48ef2a","username":"admin","firstname":"admin","lastname":"cloud","created":"2012-07-05T12:18:27-0700","state":"enabled","account":"admin","accounttype":1,"domainid":"8a111e58-e155-4482-93ce-84efff3c7c77","domain":"ROOT","apikey":"plgWJfZK4gyS3mOMTVmjUVg-X-jlWlnfaUJ9GAbBbf9EdM-kAYMmAiLqzzq1ElZLYq_u38zCm0bewzGUdP66mg","secretkey":"VDaACYb0LV9eNjTetIOElcVQkvJck_J_QljX_FcHRj87ZKiy0z0ty0ZsYBkoXkY9b7eq1EhwJaw7FF3akA3KBQ","accountid":"7548ac03-af1d-4c1c-9064-2f3e2c0eda0d"} ] } }

Where it becomes interesting is that deleting a user will be the same code but a different API call:

@app.route('/delete')
def delete():
    print request.query_string
    res={}
    for key in request.args.iterkeys():
        res[key]=request.args.get(key)
    print res
    response, error = requester.make_request('deleteUser',res,None,host,port,apikey,secretkey,protocol,path)
    return response

You would call it to delete a user by passing the id of the user like this:

curl -X GET -G 'http://localhost:5000/delete' -d id=62d866e4-da97-46c2-a3e1-10faf6197c73
{ "deleteuserresponse" : { "success" : "true"}  }

You are deleting a resource and yet, it is still a GET call. Why not using a DELETE call to delete a resource ? This would be more intuitive and a nice use of the HTTP grammar. The same situation will occur for updating a user or creating a user, still a GET while we could use a POST and a PATCH. In CloudStack-Flask I added some routes to create a proper REST service. For example a route becomes:

@app.route('/user/', methods=['GET','DELETE','PATCH'])
def user(uuid):
    if request.method =='GET':
        response, error = requester.make_request('listUsers',{'id':uuid},None,host,port,apikey,secretkey,protocol,path)
        return response
    elif request.method =='PATCH':
        data = request.json
        data['id']=uuid
        response, error = requester.make_request('updateUser',data,None,host,port,apikey,secretkey,protocol,path)
        return response
    else:
        response, error = requester.make_request('deleteUser',{'id':uuid},None,host,port,apikey,secretkey,protocol,path)
        return response

The id of the user is specified in the URL. The user is the actual web resource whose state we are changing. And the HTTP method is used to determine the type of action. In our case, the GET lists the user information, the PATCH updates the parameters of the user and the DELETE deletes the user. The id is now part of the URI and not a query parameters

curl -X GET http://localhost:5000/user/b3b60a8d-df6f-4ce6-a6f9-6194907457a5
{ "listusersresponse" : { "count":1 ,"user" : [  {"id":"b3b60a8d-df6f-4ce6-a6f9-6194907457a5","username":"john","firstname":"sebgoa","lastname":"goa","email":"runseb@gmail.com","created":"2013-04-12T05:09:10-0700","state":"enabled","account":"admin","accounttype":1,"domainid":"8a111e58-e155-4482-93ce-84efff3c7c77","domain":"ROOT","accountid":"7548ac03-af1d-4c1c-9064-2f3e2c0eda0d"} ] } }

curl -X  DELETE http://localhost:5000/user/b3b60a8d-df6f-4ce6-a6f9-6194907457a5
{ "deleteuserresponse" : { "success" : "true"}  }

curl -X  PATCH -H "Content-Type: application/json" http://localhost:5000/user/1fea6418-5576-4989-a21e-4790787bbee3 -d '{"firstname":"foobar"}'
{ "updateuserresponse" :  { "user" : {"id":"1fea6418-5576-4989-a21e-4790787bbee3","username":"runseb","firstname":"foobar","lastname":"goa","email":"joe@smith.com","created":"2013-04-10T16:52:06-0700","state":"enabled","account":"admin","accounttype":1,"domainid":"8a111e58-e155-4482-93ce-84efff3c7c77","domain":"ROOT","apikey":"Xhsb3MewjJQaXXMszRcLvQI9_NPy_UcbDj1QXikkVbDC9MDSPwWdtZ1bUY1H7JBEYTtDDLY3yuchCeW778GkBA","secretkey":"gIsgmi8C5YwxMHjX5o51pSe0kqs6JnKriw0jJBLceY5bgnfzKjL4aM6ctJX-i1ddQIHJLbLJDK9MRzsKk6xZ_w","accountid":"7548ac03-af1d-4c1c-9064-2f3e2c0eda0d"} }  }

Identify your resources/entities and use the HTTP grammer to modify their state. Don't forget to check my cloudstack-flask app, it's very basic right now but could be a nice REST wrapper doubled-up with a bootstrap based UI, we will talk about the web views in the next post.

Tuesday, April 09, 2013

The Tuesday CloudStack Silly Hack

The problem with middleware/backend work is that nobody sees what you do and since I am terrible at graphics/design and know nothing of User Interface principles I am pretty much stuck in the dark. So today I invested couple hours on the Tuesday Silly CloudStack Hack. It is made of Flask, a good read, Twitter Bootstrap and some stolen code from CloudMonkey

Flask is a terrific web microframework for Python. Of course I like Python so I think Flask is terrific. It is also great because you can use it to design clean REST services. Bootstrap is en vogue these days, and CloudMonkey, also written in Python is the new CloudStack command line interface boasting some cool features, like auto-completion, interactive shell and so on.

I will keep it short, grab requester.py from the CloudMonkey source tree, it will help you make API calls to a CloudStack instance. Create a simple script with flask, and set your CloudStack endpoint variables, plus the keys (I am using DevCloud):

import requester

from flask import Flask, url_for, render_template, request
app = Flask(__name__)

apikey='plgWJfZK4gyS3mOMTVmjUVg-X-jlWlnfaUJ9GAbBbf9EdM-kAYMmAiLqzzq1ElZLYq_u38zCm0bewzGUdP66mg'
secretkey='VDaACYb0LV9eNjTetIOElcVQkvJck_J_QljX_FcHRj87ZKiy0z0ty0ZsYBkoXkY9b7eq1EhwJaw7FF3akA3KBQ'
path='/client/api'
host='localhost'
port='8080'
protocol='http'

Setup a route that you will use to trigger a call to CloudStack. Something like this:

@app.route('/users')
def listusers():
    response, error = requester.make_request('listUsers',{},None,host,port,apikey,secretkey,protocol,path)
    resp=json.loads(str(response))
    return render_template('users.html',users=resp['listusersresponse'])

Now Download Bootstrap and stick it in a static directory in your Flask application. Then create html template files using the jinja2 syntax, something like this:

{% extends "base.html" %}

{% block content %}

{% if users %}
{{ users }}
{% else %}
Hello World!
{% endif %}

{% endblock content %}
sebmini:templates sebastiengoasguen$ 

Now run the app with Python and hit http://localhost:5000 and bang, you just got yourself your quarter end Bonus....! Well not quite, but that's a start :)

Joke aside, this should be the start of a fun Google Summer of Code project, I will put it on github if there is interest. Also if you want another silly hack, push requester.py to your android phone and using SL4a you can make calls to CloudStack from your phone...Silly CloudStack Wednesday hack anyone ?

Monday, March 25, 2013

Quantifying the Apache CloudStack Community

CloudStack is now an Apache Top Level Project (TLP) at the Apache Software Foundation (ASF), the announcement just came out. What the incubation period has meant for CloudStack has nothing to do with code maturity. CloudStack was mature and used in enterprise settings before it entered incubation at the ASF. What incubation meant was that CloudStack evolved into an open source community, self-governed by the Apache Way: transparency, meritocracy, respect, non-affiliation and consensus in no particular order. The community has learned and demonstrated that it understands the principles and processes laid by the Apache Software Foundation and that it can now operate more autonomously.

Growing an open source community is challenging, folks who participate come from various backgrounds, may seldom meet and interact mostly via emails, social media, instant messaging. Participants come from all over the world, work in different time-zones and donate their time after (and sometime while) dealing with day jobs and family. Participants rally around a project that they deem interesting, sometime just to land a hand for a few months, or sometimes because their day job requires them to do it. In that very heterogeneous and fluctuating mix, an open source software community emerges, self-governed, sustainable and non-affiliated. In the last 12 months CloudStack has done just that, building a community from the ground up, developing and understanding the principles laid out in our bylaws, adapting -if need be- people's way of developing software, getting to know each other, welcoming new members every day and setting the foundation for a sustainable software.

When growing a community it is fairly natural to want to measure how well we are doing and how healthy the community is. Over the last several months I have started collecting some data to analyze our community, trying to see how we were doing and interacting. I mostly looked at our public mailing lists doing a study similar to the one done about comparing CloudStack, OpenNebula, OpenStack and Ecualyptus. Secretly, this was also a good way for me to sharpen a few skills on BigData, not that big actually but I used MongoDB instead of MySQL so that qualifies as BigData :). Defining membership in an open source community is a challenge since there is no concept of membership, even the concept of contribution is ill-defined. What constitutes a contribution ? Which channels need to be considered ? In the case of ASF for instance, contribution to code may only mean being a committer, but a committer is someone with write access to the code. Just counting committers will leave out all the folks sending patches, doing testing, doing user support, translating documentation, giving talks and so on. Also while at the ASF everything happens on the mailing list, what about IRC channels, social media like Facebook, Twitter and Linkedin, and what about other communities that may arise around a particular software: sub-projects, user groups etc. In this analysis I decided to only look at our public mailing lists but there is more to it than just this data source.

The two figures below show the number of individual contributors measured by unique email addresses used to send messages to the users and developers mailing lists. The red lines represent data from the users and developers mailing list prior to entering incubation at the ASF. The blue lines represent the ASF specific lists. Significant is the impact that the move to the ASF has had on the number of contributors. The developers list has peaked over 200 per month and the users list has peaked over 150 per month so far (figure on the right). The last data point is March (as of March 21st) and numbers will go up by the end of the month. The graph on the right shows the accumulation of contributors, adding all unique email addresses every month into a set. This shows us again that the move to ASF has had a huge impact on the growth rate of the community and that both list grow at relatively the same pace. Adding the accumulated number of contributors to both list and removing duplicates present in both sets, this gives us a magic number of 722 CloudStack contributors to date.

As mentioned earlier these numbers of contributors are different from the number of Apache CloudStack committers. According to our bylaws contributors can become committers and gain write access to the code when invited by the Project Management Committee (PMC). Just today we welcomed three new committers for a current total of 54. This number is again relative in terms of contribution to code, since committers apply patches from contributor who are not yet committers (I know confusing :) ). A quick look at our git repo, shows a current total of 159 code contributors. To that we could also add the 32 contributors who helped with the translation via transifex which may or may not have participated in the mailing lists.

These numbers show a growing community sparked by the move to the ASF. While at the start of incubation the initial set of committers and contributors where only from Citrix who donated the code, we are also seeing a diversification in the number of companies involved. Talking about affiliation is actually a cardinal sin of the Apache Way. At the ASF only individuals matter, but it is fair to say that for CloudStack to be successful we need to see adoption/participation by a diverse set of companies. The two figures below show just that with the number of companies identified by the email domain used by the contributors. This is not perfect since contributors often do not use their work email but gives a good idea of the trend. Similarly to the plots about contributors we plot the number of companies (really email domains). Clearly the growth in the number of companies involved has increased since joining the ASF, we currently see around 50 companies involved in CloudStack every month. Accumulating all these companies we reach almost 200 on both lists. Removing duplicates from both sets we estimate the total number of companies to 272. Even if some of those companies are only represented by a single individual this is still a very strong number that shows great diversification. Interestingly over the last three months we see that the participation in the user list has shown more diversity than on the developer list.

Finally, looking at the cloudstack-commits mailing list we try to identify the number of committers to the code. The figure below shows the number of committers and the number of commits measured by number of emails and unique email addresses used on the commits mailing list. We already mentioned that we had 54 committers but that some of those committers gained their rights based on contribution which could be as diverse as development, user support, translation etc. Therefore it is no surprise to see the number of committers peaking at 35 and the accumulated number reaching 45. The number of commits is growing, reaching 1500 a month during the 4.0 release, easing up during christmas time and peaking again over 2500 per month prior to code freeze of the 4.1 release.

All in all, analyzing lots of emails showed me that moving to ASF has had a tremendous impact on CloudStack, with over 700 contributors, close to 60 committers, 30 translators, over 1 million lines of code, CloudStack is self-governed and here to stay.