Skip to Content
Technical Articles

CloudFoundryFun #1 – Upgrade Cloud Foundry With A New REPL Feature

In this initial blog post of my new series, I’m going to show you can get to know Cloud Foundry better. For this we leverage the so called read-eval-print-loop (REPL). A REPL is a unique sandbox you can leverage to code in the environment your applications live in and therefore it:
  • Provides you with insights no IDE or documentation can offer
  • Helps you to stay in the zone/flow
  • Makes your application runtime more tangible
  • Allows you to “interview” your applications or services

Make your applications more tangible!

The REPL can make your Cloud Foundry runtime as tangible as the red ball. Image credits:MIT’s Tangible Media Lab
There are many things you have to learn when you start to develop in the Cloud Foundry environment. Often this leads to confusion and frustration. As stated above, the REPL can help you to tackle those problems. Node.js and Python come with such a REPL and both frameworks can run in SAP Cloud Platform Cloud Foundry.

So, let’s REPLifying the SAP Cloud Platform!

Toy Problem

For the sake of simplicity, I decided to keep the problem as simple as possible:

Problem: Extract a list of bound services from the environment

The problem can be easily solved with the npm package cfenv and the following snippet:

const cfenv = require('cfenv');
console.log(cfenv.getAppEnv());

You obviously won’t get the expected result when you run this snipped in your local environment. However, it would work if we were able to have a REPL running in our Cloud Foundry environment.

REPLifying

I went through four iterations to REPLify the SAP Cloud Platform. Starting with a very naïve approach.

Iteration 1: Connect to the application via SSH

This is a very simple approach. I connected to a “blank” Cloud Foundry app via SSH and started the Node REPL with the usual command (./node). The node command (../deps/0/node/bin/node) looks a little bit strange here. Inside the runtime, the node binary is not in the environment variables path and therefore we need to refer to it in this way.

cf enable-ssh  iteration_ssh
cf restart  iteration_ssh
cf ssh  iteration_ssh
../deps/0/node/bin/node

 

This naïve approach works fine but also comes with some disadvantages. The bound Cloud Foundry services need to be created in the cockpit beforehand. The application (node/python) dependencies need to declared at design time as well. Another issue is that this approach builds on the CF CLI and on your developer account. I consider this as a “con” even though this restriction might be desired in some cases.

✅Pros ⛔️Cons
Can be used by every CF dev Installation of npm or pip package at “design time”
Runs in the Terminal/Shell Need to define CF services in the cockpit
Need to bind CF services manually after creation
Need to configure the CF app
Requires CF CLI
No debugging
Feels like a hack

Iteration 2: Build an OpenUI5-based REPL

This iteration improves the accessibility. I created a simple OpenUI5 app with the necessary backend logic. This way we can “eat our own dog food”.

Luckily, OpenUI5 has a code editor control and syntax highlighting capabilities. We can use this control for the code input, a button to submit the code and a field to print the output and voilà:

I don’t want to go into detail on the backend part and therefore I only sketch the outlines:

I save the submitted code (payload of the POST request) as a javascript file and run it in a child process. This is probably the worst and most insecure code you’ve ever seen, which is why I won’t share it with you 😜.

The approach to make the REPL accessible from any web browser by any authorized user is quite nice. But there are still some disadvantages to this approach:

✅Pros ⛔️Cons
Easy deployment Need to define CF services in the cockpit
Can be used by any authorized users Need to bind CF services manually after creation
Use from any device with a web browser No access to package managers
Cannot bind CF services at runtime
No debugging capabilities

Iteration 3: Deploy a Standalone Docker Image to Cloud Foundry

The previous iteration made me realize, I basically want to implement an IDE. Which doesn’t make sense for numerous reasons (e.g. requires too much time, too complex). Besides, there are already many great web-based IDEs out there. As we know, Cloud Foundry allows us to deploy any Docker image. This means we don’t have to write an IDE, we can simply pick a docker image of our favorite cloud IDE! I choose Theia because it has a very low footprint which can run in the trial landscape.

Create a manifest.yml file with the following payload and run cf push to deploy the image.

---
applications:
- name: theia
  memory: 1G
  disk_quota: 2G
  random-route: true
  docker:
    image: theiaide/theia-python

  services:
  - uaa
  - dest
  - conn
  - devfabric.channel1

Now we have a running web app which offers far more than just a REPL. This IDE allows you to create files and access to a Terminal. With this terminal, you can install any npm or python module and execute scripts. You can even use breakpoints if you know how to debug in the terminal. In our case we need to:

  1. Click on files and select a workspace (e.g. home)
  2. Go to Terminal in the toolbar and select New
  3. Run npm install cfenv
  4. Run touch app.js and use the editor or the terminal to paste our solution snippet
  5. Run node app.js

Please keep in mind that everyone who knows the URL of the service can access this IDE. Besides, we still need to create the bound cloud services before deployment.

✅Pros ⛔️Cons
Easy deployment Need to define CF services in the cockpit
Works on any web browser Need to bind CF services manually after creation
Access to package managers No Authentication
Basic debugging capabilities
Rich IDE interface

Iteration 4: Deploy a Docker Image along with Services

In the last iteration, we transform the manifest.yml file into a mtad.yaml. The manifest.yml descriptor file is a “pure” Cloud Foundry artifact and describes a single microservice. In constrast, the mtad.yaml is an SAP Cloud Platform Cloud Foundry artifact and describes a set of microservices. This file describes each module (=microservice) and the bound services.

The mtad.yaml file could look like this:

_schema-version: 3.2.0
ID: dockerapp
description: Enter description here
version: 0.0.1
modules:
- name: theia-ide
  type: javascript.nodejs
  requires:
  - name: destination-service
  parameters:
    disk-quota: 2G
    memory: 2G
    docker:
      image: theiaide/theia-python
resources:
- name: destination-service
  type: org.cloudfoundry.managed-service
  parameters:
    service: destination
    service-plan: lite
Here we define a destination service and bind it to our docker image. During deployment, the cloud platform will create the service if necessary.
We package the descriptor file to an MTA archive and deploy it to Cloud Foundry.
mbt assemble
cf deploy mta_archives/dockerapp_0.0.1.mtar
This finalizes the fourth iteration of the Cloud Foundry REPL.
✅Pros ⛔️Cons
Easy deployment No Authentification
Works on any web browser
Access to package managers
Define Cloud services in descriptor file
Basic debugging capabilities
Rich IDE interface

Summary

With this setup, you can upgrade your Cloud Foundry to an actual sandbox and do with it what sandboxes are for:
Experiment and have fun!

Fun in a sandbox via GIPHY

You have also learned how to:

  • Deploy a REPL in Cloud Foundry
  • SSH into running CF app
  • Deploy pure Docker image to Cloud Foundry
  • Deploy Docker images along with Cloud services to SAP Cloud Platform Cloud Foundry

 

Do you think a REPL in the Cloud is useful or do you have ideas for the next iteration of this project? Please let me know in the comments!

Update 2/13/2019: Check out this video by DJ Adams if you’d like to see the REPL in action 🙂

Update 2/25/2019: Step 4 work in the trial landscape as well now!

About this series

This was the initial blog post of my monthly new series #CloudFoundryFun. The name already says all there is to it, this series won’t be about building enterprise apps on Cloud Foundry. I think there are already plenty of great posts about those aspects out there. This series rather thinks outside the box and demonstrates unconventional Cloud Foundry use-cases. And sometimes it might be pure entertainment 🙃.

 

Be the first to leave a comment
You must be Logged on to comment or reply to a post.