Haskell & Happstack on CloudFoundry

For the past few weeks I have been running some experiments on Cloud Foundry. I was hoping to combine my understanding of the internal workings of VMWare’s Cloud Application Platform (vcap) with my Haskell code.

So, to make sure that we can run Haskell “in the cloud” (especially considering Julian Porter’s CloudHaskell work), I decided to include the Haskell runtime and Happstack framework in Cloud Foundry.

Success!

And guess, what? It worked!

Before I tell you all the details and point you to my Github fork of vcap, I’ll show you, starting with Figure 1, which shows that vmc runtimes now includes [The Glorious Glasgow--ridiculous, I know!] Haskell compiler.

Figure 1. GHC runtime

Next, I have the Happstack framework; Figure 2 shows the output of running vmc frameworks.

Figure 2. Happstack framework

Moving on, I’m going to deploy trivial Haskell/Happstack application. (Naturally, I could write some amazing Haskell code, but Hello World is the most didactical!). The source is

module Main where

import Happstack.Server (nullConf, simpleHTTP, toResponse, ok)

main :: IO ()
main = simpleHTTP nullConf $ ok "Hello, World! Haskell is COOL!"

Now that I have the application, let’s deploy it in CloudFoundry, using the usual vmc push command. The updated vmc recognises that the app is indeed a Haskell/Happstack one and selects the appropriate runtime/framework combination. (Viz Figure 3).

Figure 3. vmc push

Finally, we need to show you that the application is indeed running. So, on to the browser and go to http://haskellapp.vcap.me and see Figure 4.

Figure 4. The result

The code

Let’s take a look at what we had to do to get it running.

Hacking vcap

To make sure that the Cloud Controller understands the new runtime and framework, I modified the ‘app’ model by adding the following code:

Runtimes = %w[ruby18 ruby19 java node php erlangR14B02 python26 haskell]
Frameworks = %w[sinatra rails3 java_web spring grails node php otp_rebar lift wsgi django happstack unknown]
...
...
when "happstack/1.0"
    self.framework = 'happstack'
    self.runtime   = 'haskell'
end

Next up is the cloud_controller.yml file

  haskell:
    version: "[6-7].*"

Now we need make sure that the ‘dea’ is configured, so the dea.yml file

  haskell:
    executable: /usr/bin/runhaskell
    version: 6.12.1
    version_flag: '--version'
    environment:

So far the cloud controller knows about the runtime and framework and the dea is configured to deal with them as well. Now we need make sure that a Haskell/Happstack app can be staged in cloud foundry. We added the HappstackPlugin and the manifest for Happstack.

class HappstackPlugin < StagingPlugin
  def framework
    'happstack'
  end

  def stage_application
    Dir.chdir(destination_directory) do
      create_app_directories
      copy_source_files
      create_startup_script
    end
  end

  def start_command
    "runhaskell Main.hs"  #Equivalent of 
  end

  ...
end
---
name: "happstack"
runtimes:
  - haskell:
      version: '6.12.1'
      description: 'The Glorious Glasgow Haskell Compilation System'
      executable: /var/vcap/runtimes/haskell-6.12.1/bin/runhaskell
      default: true
app_servers:
detection:
  - "*.hs": true
staged_services:

In this post, I’m ignoring the pains of installing Haskell/Happstack on Ubuntu 10.04–there’s a long blog post coming up about that soon! For the brave, take a look at setup/vcap_setup in the vcap repository.

Hacking vmc

Not a lot but still you would need the following to get vmc to understand the new runtime and framework: frameworks.rb

module VMC::Cli

  class Framework

    DEFAULT_FRAMEWORK = "http://b20nine.com/unknown"
    DEFAULT_MEM = '256M'

    FRAMEWORKS = {
      ...,
      'Happstack'         => ['happstack',  
         { :mem => '128M', :description => 'Happstack Web Application'}]
    }

    class << self

      def known_frameworks
        FRAMEWORKS.keys
      end

      def lookup(name)
        return Framework.new(*FRAMEWORKS[name])
      end

      def detect(path)
        Dir.chdir(path) do
          ...
          ...
          # Happstack
          elsif !Dir.glob('*.hs').empty?
            return Framework.lookup('Happstack')
             
          end
        end
        nil
      end

    end

...
end

References & Downloads

We’ll send a pull request to the VMWare guys soon (after a bit of gold platting…), but in the meantime, you can fork https://github.com/anirvanc/vcap and https://github.com/anirvanc/vmc and get hacking!

This entry was posted in Ani's Blog and tagged , , , , , . Bookmark the permalink.

16 Responses to Haskell & Happstack on CloudFoundry

  1. Josh Long says:

    That’s *awesome*!!

  2. Anirvan Chakraborty says:

    Thanks a lot Josh :)

    Hope to get the pull request going soon!

  3. Sateesh says:

    Hi,

    I have a small doubt. I have seen that your application will start with command “runhaskell Main.hs”. But what if my framework has different file names for different user to start the application. for example in mojolicious framework we need to start the application by command morbo .pl of perl language. How to specify that. Here the file name is dynamic. We can provide a option to user to specify the file name that is used to run the application in some app.yml file. but how to access that file? Do we need to access something like “destination_directory/app.yml”?

    Thanks in advance,
    Sateesh B.

  4. Anirvan Chakraborty says:

    Hi Sateesh,

    From my understanding of CloudFoundry, VCAP provides the platform on which applications (of a general form) can be deployed. As a result, for a particular framework you would need to maintain a general form for it to really work on a global scale. For that reason only, I’ve generalised running haskell apps by running a ‘main’ file. I know it is not probably the best thing to do, but it felt like a pretty good way to start!
    I’m not sure if you can actually configure running an app on a per user basis for the entire CloudFoundry instance or not. More importantly, I don’t think it would be a good idea to do that.
    If you absolutely need different running strategy per user for your applications then you would have to look deep into VMC for doing that sort of thing. Have a look at vmc/tree/master/lib/cli/frameworks.rb for inspiration!
    Hope this helps.

    Thanks,
    Ani.

  5. Sateesh says:

    Hi,

    I have added a new framework using the steps provided by you. VMC is successfully detecting the framework, but when during creating application I am getting following error

    C:\Users\sateesh_bodla\Desktop\mojo-helloworld>vmc push
    Would you like to deploy from the current directory? [Yn]:
    Application Name: mojofirst
    Application Deployed URL: ‘mojofirst.vcap.me’?
    Detected a Mojolicious Web Application, is this correct? [Yn]:
    Memory Reservation [Default:128M] (64M, 128M, 256M, 512M or 1G)
    Creating Application: Error 300: Invalid application description

    when I see the cloud controller logs I have seen that runtime and framework values are not passed to vcap. I have restarted the VCAP after editing the code. But still its not working. Can you please let me know where am I missed the code. I have checked every thing. Below is the error from cloud controller log:

    [2011-12-23 18:18:28] cc – 24255 8f5b 73c3 ERROR — app: Failed to save new app errors: {:runtime=>["can't be blank", "is not included in the list"]}
    [2011-12-23 18:18:28 +0530, :USER, "sateesh@test.com", "POST:/apps", "mojofirst", :FAILED, "Invalid application description"]

    Thanks in advance,
    Sateesh B.

  6. Sateesh says:

    Adding to above comments, when I run vmc runtime or vmc framework my runtime or framework is not listed.

  7. Sateesh says:

    Also I have added runtime and framework in app model.

  8. Anirvan Chakraborty says:

    Hello Sateesh,

    Without looking at your code it’s very difficult for me to resolve the issue you are having. But, I would advice you to verify the following:
    1. Make sure that you are running the correct version of VCAP, as by default the VCAP install script will try and run against the CloudFoundry github source.
    2. Make sure you have removed any older version of VMC gem installed on your machine and carefully install VMC from your source.

    Other than that I can’t think of anything else that would cause the issue, as it’s clear that the VMC you are running to get the error messages doesn’t recognise your new runtime!

    At this moment I could only wish you happy hacking during the holiday period!

  9. Sateesh says:

    Hi Ani,

    Thanks for your reply. As you said I have installed the latest VCAP and done this proceedure. Also I have changed VMC code that is already installed on my system.

    Do we need to install this VMC again? VMC is detecting the application as Mojolicious, but it is not listing the frameworks / runtimes when I am using the command vmc runtimes / vmc frameworks.

    Can you please provide any solution for solving this problem.

    Thanks in advance,
    Sateesh B.

  10. Sateesh says:

    Should I need to compile or do any other thing to reflect the changes.

  11. Sateesh says:

    Hi,

    I found that even when I run rake build in vcap_staging, it is not creating the files or manifests in /usr/local/rvm/gems/ruby-1.9.2-p180/gems/vcap_staging-0.1.25/lib/vcap/staging/plugin/. When I have manually copied the files, runtime and frameworks are detected.

    But the issue now is my application is not getting started. Can you help me on how to start the application. I have installed the specific softwares on the vcap server and able to run the application manually and access with URL. but when I written the script in plugin.rb, it is not starting. I am unable to find the error.

    Thanks in advance,
    Sateesh B.

  12. Sateesh says:

    Script in plugin.rb:

    class MojoliciousPlugin < StagingPlugin
    def framework
    'mojolicious'
    end

    def resource_dir
    File.join(File.dirname(__FILE__), 'resources')
    end

    def stage_application
    Dir.chdir(destination_directory) do
    create_app_directories
    copy_source_files
    create_startup_script
    end
    end

    def start_command
    "morbo app.pl"
    end

    private

    def startup_script
    end

    end

  13. Anirvan Chakraborty says:

    Hello Sateesh,

    Have you modified ‘vcap_setup’ script to actually install your runtime? I think you would need to run the normal install script but from your modified VCAP sources get the installation complete!

    The plugin code on your ‘MojoliciousPlugin’ looks OK to me! But, without any error message or looking physically in your setup it’s almost impossible for me to even guide you any further! It’s worth verifying whether you have modified the framework specific ‘yml’ file in vcap staging or not?

    Hope this helps!

  14. Pingback: Adding a Runtime and Framework to an older Cloud Foundry « Programming Gems (on GemStone)

  15. cherry says:

    Hi.I did as the steps you list above.Now via command “vmc runtimes” and “vmc frameworks”, I can see what I added. When I use vmc push to push an application, it will show Ok until Starting the application. Actually I saw nothing in the droplets\apps. Can you help me? Just give some ideas.Thanks a lot.

  16. Anirvan Chakraborty says:

    Hi Cherry,
    I’m not sure exactly what problems you are facing! Without looking at your code it would be difficult for me to advice.

    Please beware of the VMC/CloudFoundry versions you are using, as it’s been a long time since the blog was written and CloudFoundry has gone through a lot of changes since then. I haven’t managed the time to update the blog with the current CloudFoundry version.

    You might want to have a look at http://programminggems.wordpress.com/2012/01/31/adding-a-runtime-and-framework-to-an-older-cloud-foundry/ for a more recent approach. James have done a great job with his writeup.

    HTH!

Leave a Reply