cloudsoft.io

Bundling

Bundling Catalog Resources

It is possible to upload catalog items and associated resources as a single bundle to AMP. This is useful when you have a blueprint that needs to reference external scripts, icons, config files or other resources, or when you have multiple blueprints that you want to keep in sync. AMP will persist any uploaded bundles so that they are available after a restart or on HA failover.

The bundle must be a ZIP file including a catalog.bom in the root. (The br CLI will create a ZIP from a local folder, for convenience.) The catalog.bom must declare a bundle identifier and a version, following AMP’s versioning rules. AMP will keep track of that bundle, allowing items to be added and removed as a group, and associated resources to be versioned and included alongside them. With SNAPSHOT-version bundles, it allows replacement of multiple related items at the same time, and in advanced cases it allows setting up dependent bundles (specified as brooklyn.libraries or, for people familiar with OSGi, the Required-bundle manifest header) which will be searched if a blueprint in one bundle references resources from another bundle.

Resources in the bundle can be referenced from the catalog.bom by using the classpath: URL protocol, as in classpath://path/to/script.sh. This can also be used to load resources in explicitly declared dependent bundles, using classpath:bundle:version:/path/to/file.sh; if omitted, typically the bundle of the entity resolving the link will be searched along with its OSGi dependencies and brooklyn.library dependencies. (This means if you define an entity type in a bundle, resources in that bundle will be found automatically, but if your bundle defines a composite blueprint referencing other types as children, those children will not automatically search your bundle and a reference will be needed.)

Optionally, an icon can be provided for the bundle using bundleIconUrl, which accepts http:, https:, and classpath: protocols, e.g. classpath://brooklyn/icons/server.svg or https://brooklyn.apache.org/style/img/bridge.png

Example

In this example, we will create a simple my-server catalog item, bundled with a simple script. The script will be run when launching the server.

First, create a folder called bundleFolder, then add a file called myfile.sh to it. The contents of myfile.sh should be as follows:

echo Hello, World!

Now create a file in bundleFolder called catalog.bom with the following contents:

brooklyn.catalog:
  bundle: MyServerBundle
  bundleIconUrl: classpath://brooklyn/icons/server.svg
  version: 1.0.0
  items:  
    - id: my-server
      item: 
        type: org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess
        brooklyn.config:
          files.runtime:
            classpath://myfile.sh: files/myfile.sh
          launch.command: |
            chmod +x ./files/myfile.sh
            ./files/myfile.sh        
        checkRunning.command: echo "Running"  
        

The bundle: MyServerBundle line specifies the OSGI bundle name for this bundle. Any resources included in this bundle will be accessible on the classpath, but will be scoped to this bundle. This prevents an issue where multiple bundles include the same resource.

To create the bundle, simply use the br command as follows. This will create a zip and send it to AMP. Please note you can also specify a zip file (either on the file system or hosted remotely):

br catalog add bundleFolder

This will have added our bundle to the catalog. We can now deploy an instance of our server as follows. Please note that in this example we deploy to localhost. If you have not setup your machine to use localhost please see the instructions here or use a non localhost location.

location: localhost
services:
- type: my-server

We can now see the result of running that script. In the UI find the activities for this application. The start activity has a sub task called launch (you will have to click through multiple activities called start/launch. Looking at the stdout of the launch task you should see:

Hello, World!

Alternatively you can view the script directly if you run the following against localhost. Please note that brooklyn-username and the id of your app will be different.

cat /tmp/brooklyn-username/apps/nl9djqbq2i/entities/VanillaSoftwareProcess_g52gahfxnt/files/myfile.sh

It should look like this:

echo Hello, World!

Now modify myfile.sh to contain a different message, change the version number in catalog.bom to 1.1.0, and use the br command to send the bundle to the server.

If you now deploy a new instance of the server using the same YAML as above, you should be able to confirm that the new script has been run (either by looking at the stdout of the launch task, or looking at the script itself)

At this point, it is also possible to deploy the original Hello, World! version by explicitly stating the version number in the YAML:

location: localhost
services:
- type: my-server:1.0.0

To demonstrate the scoping, you can create another bundle with the following catalog.bom. Note the bundle name and entity id have been changed, but it still references a script with the same name.

brooklyn.catalog:
  bundle: DifferentServerBundle
  version: 1.0.0
  item:  
    id: different-server
    type: org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess
    brooklyn.config:
      files.runtime:
        classpath://myfile.sh: files/myfile.sh
      launch.command: |
        chmod +x ./files/myfile.sh
        ./files/myfile.sh
        
      checkRunning.command:
        echo "Running"  

Now create a new myfile.sh script with a different message, and use the br command to send the bundle to AMP.

Now deploy a blueprint which deploys all three servers. Each of the three deployments will utilise the script that was included with their bundle.

location: localhost
services:
- type: my-server:1.0.0
- type: my-server:1.1.0
- type: different-server

Note: All three entities copy a file from classpath://myfile.sh, but as they are in different bundles, the scripts copied to the server will be different.