Skip to content

Latest commit

 

History

History
285 lines (240 loc) · 9.42 KB

buildpack-lab.adoc

File metadata and controls

285 lines (240 loc) · 9.42 KB

PS@E Buildpack Lab

Prerequisites

  • Git

  • A Ruby version manager: RVM or Rbenv

  • The ``Hello World'' cities app you created earlier

Intro

This lab will guide you through working with the Cloud Foundry Java Buildpack. You’ll learn how to obtain the buildpack source code, extend it, package it, deploy it, and test it. At the end of this lab you should feel comfortable doing hands-on buildpack work for a customer.

Steps

  1. Clone the Cloud Foundry Java Buildpack from GitHub:

    $ git clone https://github.com/cloudfoundry/java-buildpack
    $ cd java-buildpack
  2. Open the Buildpack source code directory in your favorite editor.

  3. We’ll add a framework component that will set a Java system property containing a timestamp that indicates when the application was staged. To do that, first create java-buildpack/lib/java_buildpack/framework/staging_timestamp.rb and add the following contents:

    require 'java_buildpack/framework'
    
    module JavaBuildpack::Framework
    
      # Adds a system property containing a timestamp of when the application was staged.
      class StagingTimestamp < JavaBuildpack::Component::BaseComponent
        def initialize(context)
          super(context)
        end
    
        def detect
          'staging-timestamp'
        end
    
        def compile
        end
    
        def release
          @droplet.java_opts.add_system_property('staging.timestamp', "'#{Time.now}'")
        end
      end
    end
  4. Next we need to ``turn on'' our new framework component by adding it to java-buildpack/config/components.yml as seen here:

    frameworks:
      - "JavaBuildpack::Framework::AppDynamicsAgent"
      - "JavaBuildpack::Framework::JavaOpts"
      - "JavaBuildpack::Framework::MariaDbJDBC"
      - "JavaBuildpack::Framework::NewRelicAgent"
      - "JavaBuildpack::Framework::PlayFrameworkAutoReconfiguration"
      - "JavaBuildpack::Framework::PlayFrameworkJPAPlugin"
      - "JavaBuildpack::Framework::PostgresqlJDBC"
      - "JavaBuildpack::Framework::SpringAutoReconfiguration"
      - "JavaBuildpack::Framework::SpringInsight"
      - "JavaBuildpack::Framework::StagingTimestamp" #Here's the bit you need to add!
  5. Now that we’ve extended the buildpack, we need to package it. This is achieved using a Rake task. Before we do that, we need to install the dependent Ruby gems for the buildpack using Bundler. We’ll also leverage Bundler to run the Rake task.

    $ bundle install
    $ bundle exec rake package OFFLINE=true

    Toward the end of the output, you should see something like the following, which indicates where your buildpack package as been created:

    cp resources/tomcat/conf/context.xml build/staging/resources/tomcat/conf/context.xml
    cp resources/tomcat/conf/logging.properties build/staging/resources/tomcat/conf/logging.properties
    cp resources/tomcat/conf/server.xml build/staging/resources/tomcat/conf/server.xml
    Creating build/java-buildpack-158e5a6.zip
  6. Now it’s time to upload our extended Java buildpack to Cloud Foundry. We’ll leverage the cf CLI. Ensure that you’re logged in to your CF instance as an admin user.

    $ cf api
    API endpoint: https://api.cf.deepsouthcloud.com (API version: 2.2.0)
    
    $ cf login
    API endpoint: https://api.cf.deepsouthcloud.com
    
    Email> admin
    
    # Remainder omitted...

    To add our buildpack, we’ll leverage cf create-buildpack. Run that with zero command-line options to see how the command works:

    $ cf create-buildpack
    FAILED
    Incorrect Usage.
    
    NAME:
       create-buildpack - Create a buildpack
    
    USAGE:
       cf create-buildpack BUILDPACK PATH POSITION [--enable|--disable]
    
    TIP:
       Path should be a zip file, a url to a zip file, or a local directory. Position is an integer, sets priority, and is sorted from lowest to highest.
    
    OPTIONS:
       --enable     Enable the buildpack
       --disable    Disable the buildpack

    Add your buildpack to your CF instance like this (give your buildpack a unique name by appending some suffix like your initials):

    $ cf create-buildpack java-staging-ts build/java-buildpack-158e5a6.zip 0 --enable
    Creating buildpack java-staging-ts...
    OK
    
    Uploading buildpack java-staging-ts...
    OK
  7. Now it’s time to test our changes. We’ll add a very basic REST controller to our Cities application that will return the staging timestamp in response to a GET request.

    Create cities/src/main/java/org/example/cities/StagingController.java and add the following code:

    package org.example.cities;
    
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class StagingController {
    
        @RequestMapping("/staging")
        public String index() {
            String timestamp = System.getProperty("staging.timestamp");
            return "Application was staged at: " + timestamp;
        }
    }

    Repackage and repush the application (please login as the NON-ADMIN user you created in the previous lab):

    $ gradle assemble
    $ cf push -b <the name you gave your buildpack>
  8. Now let’s check the staging info provided by the Java buildpack to see that our change was effective:

    $ cf files cities staging_info.yml
    Getting files for app cities in org mstine-org / space demo as admin...
    OK
    
    ---
    buildpack_path: /var/vcap/data/dea_next/admin_buildpacks/16b81d79-2a6a-426a-8cff-6daf779eadad_93ad9995be0bd22935c4590c6986061bbb0e9c0d
    detected_buildpack: java-buildpack=158e5a6-https://github.com/cloudfoundry/java-buildpack.git#158e5a6
      java-main open-jdk-jre=1.7.0_55 spring-auto-reconfiguration=1.2.0_RELEASE staging-timestamp
    start_command: SERVER_PORT=$PORT $PWD/.java-buildpack/open_jdk_jre/bin/java -cp $PWD/.:$PWD/.java-buildpack/spring_auto_reconfiguration/spring_auto_reconfiguration-1.2.0_RELEASE.jar
      -Djava.io.tmpdir=$TMPDIR -XX:OnOutOfMemoryError=$PWD/.java-buildpack/open_jdk_jre/bin/killjava.sh
      -Xmx382293K -Xms382293K -XX:MaxPermSize=64M -XX:PermSize=64M -Xss995K -Dstaging.timestamp='2014-05-27
      15:52:41 +0000' org.springframework.boot.loader.JarLauncher

    As you can see from the output, our timestamp was added as the final -D argument in the start_command.

  9. Finally, hit your application endpoint to see that it is working as expected:

    $ curl -i http://cities.cf.deepsouthcloud.com/staging
    HTTP/1.1 200 OK
    Content-Length: 52
    Content-Type: text/plain;charset=ISO-8859-1
    Date: Tue, 27 May 2014 17:23:57 GMT
    Server: Apache-Coyote/1.1
    X-Application-Context: cities:cloud:0
    
    Application was staged at: 2014-05-27 15:52:41 +0000
  10. You did it! Congratulations on completing the lab.

BONUS: Change JRE Version

In this section you’ll update your buildpack to utilize JRE 1.8 rather than 1.7.

  1. Change java-buildpack/config/open_jdk_jre.yml as shown:

    repository_root: "{default.repository.root}/openjdk/{platform}/{architecture}"
    version: 1.8.0_+ # 1.7 becomes 1.8
    memory_sizes:
      metaspace: 64m.. # permgen becomes metaspace
    memory_heuristics:
      heap: 85
      metaspace: 10 # permgen becomes metaspace
      stack: 5
      native: 10
  2. Repackage the buildpack:

    $ bundle exec rake clean package OFFLINE=true
  3. Update your admin buildpack:

    $ cf update-buildpack java-staging-ts -p build/java-buildpack-158e5a6.zip
    Updating buildpack java-staging-ts...
    OK
  4. Repush your application (again, login as the NON-ADMIN user you created in the previous lab), watching the JRE version change:

    $ cf push
    Using manifest file /Users/pivotal/workspace/pse-training/pse-hw-module/code/manifest.yml
    
    Updating app cities in org mstine-org / space demo as admin...
    OK
    
    Uploading cities...
    Uploading app files from: /Users/pivotal/workspace/pse-training/pse-hw-module/code/build/libs/cities-0.0.1-SNAPSHOT.jar
    Uploading 735.9K, 95 files
    OK
    Binding service cities-db to app cities in org mstine-org / space demo as admin...
    OK
    
    Stopping app cities in org mstine-org / space demo as admin...
    OK
    
    Starting app cities in org mstine-org / space demo as admin...
    OK
    -----> Downloaded app package (23M)
    -----> Downloaded app buildpack cache (38M)
    -----> Java Buildpack Version: 158e5a6 | https://github.com/cloudfoundry/java-buildpack.git#158e5a6
    -----> Downloading Open Jdk JRE 1.8.0_05 from http://download.run.pivotal.io/openjdk/lucid/x86_64/openjdk-1.8.0_05.tar.gz (found in cache)
    # Remainder omitted...
  5. You can also verify your update by looking again at the staging info:

    $ cf files cities staging_info.yml
    Getting files for app cities in org mstine-org / space demo as admin...
    OK
    
    ---
    buildpack_path: /var/vcap/data/dea_next/admin_buildpacks/e26215b3-1ff9-4e0f-82ee-c7ac2c23d24c_29caed807a9b3294f2acc7bc666c6bafb767cadd
    detected_buildpack: java-buildpack=158e5a6-https://github.com/cloudfoundry/java-buildpack.git#158e5a6
      java-main open-jdk-jre=1.8.0_05 spring-auto-reconfiguration=1.2.0_RELEASE staging-timestamp
    start_command: SERVER_PORT=$PORT $PWD/.java-buildpack/open_jdk_jre/bin/java -cp $PWD/.:$PWD/.java-buildpack/spring_auto_reconfiguration/spring_auto_reconfiguration-1.2.0_RELEASE.jar
      -Djava.io.tmpdir=$TMPDIR -XX:OnOutOfMemoryError=$PWD/.java-buildpack/open_jdk_jre/bin/killjava.sh
      -Xmx389939K -Xms389939K -XX:MaxMetaspaceSize=64M -XX:MetaspaceSize=64M -Xss985K
      -Dstaging.timestamp='2014-05-27 17:58:04 +0000' org.springframework.boot.loader.JarLauncher