Apr 04, 2018 Build Better BOSH Releases Faster with Language Packs
When you're packaging your bespoke systems as BOSH releases, over and over again, you will first need a Ruby/Java/Golang/Python package for compilation or runtime. The BOSH community is now providing language packs to make it much simpler and faster. This article is a quick look and a "build a BOSH release" walk thru using the Go language pack (you can also see the resulting BOSH release).
bosh command you'll need to learn is
bosh vendor-package, and then how/when to use the
runtime.env scripts that are bundled with each language pack.
Find them all at https://github.com/bosh-packages. At the time of writing, the available language packs are:
- java - openjdk-8 and openjdk-9
- golang - golang-1.9 and golang-1.10
- ruby - ruby-2.4-r3
- python - python-2.7
Want to help make the world a better place? Pull requests for ruby-2.5 and python-3.6 would be welcomed by me so I can use them.
Note, afaik, the BOSH core team, doesn't call them "language packs". Yet.
I like "language packs", though "language releases" or packages may sound more familiar. - Dmitriy
Let's package up a sample Golang web app as a BOSH release.
First, clone the sample app locally and confirm that you know how to compile and run it:
go get github.com/cloudfoundry-community/simple-go-web-app cd $GOPATH/src/github.com/cloudfoundry-community/simple-go-web-app export MESSAGE="this is the message to display" export PORT=8000 go run main.go
Your sample Golang web app will now be running at http://localhost:8000/ and will display your
$ curl http://localhost:8000 this is the message to display
Now, let's package and run this via BOSH. First, create a workspace folder and clone the language pack. We're using
golang-release to compile our Golang application:
mkdir -p ~/workspace cd ~/workspace git clone https://github.com/bosh-packages/golang-release
Create a new BOSH release project, or use an existing one, and vendor the language pack:
gem install bosh-gen bosh-gen new simple-go-web-app cd simple-go-web-app-boshrelease
Now, the first step of magic for language packs is the
bosh vendor-package command:
bosh vendor-package golang-1.10-linux ~/workspace/golang-release
The output will look like:
Adding package 'golang-1.10-linux/48c842421b6f05acf88dc6ec17f7574dade28a86'... -- Started uploading 'golang-1.10-linux/48c842421b6f05acf88dc6ec17f7574dade28a86' (sha1=e9a18aebf2c407ce17423c22c913b6612cf4b75f) 2018/04/04 09:44:29 Successfully uploaded file to https://s3.amazonaws.com/sample-go-boshrelease/58b5770b-eff5-49f1-5b2d-f834dc80e4d3 -- Finished uploading 'golang-1.10-linux/48c842421b6f05acf88dc6ec17f7574dade28a86' (sha1=e9a18aebf2c407ce17423c22c913b6612cf4b75f) Added package 'golang-1.10-linux/48c842421b6f05acf88dc6ec17f7574dade28a86'
Your BOSH release will now have a new package:
$ git status .final_builds/ packages/golang-1.10-linux/
Commit it to your repo:
git add . git commit -m "add golang-1.10-linux langage pack"
Submodule the sample Golang app into the
git submodule add https://github.com/cloudfoundry-community/simple-go-web-app \ src/gopath/src/github.com/cloudfoundry-community/simple-go-web-app
simple-go-web-app BOSH package, that compiles itself with our
golang-1.10-linux language pack.
bosh-gen package simple-go-web-app \ -d golang-1.10-linux \ --src gopath
packaging/simple-go-web-app/packaging to load the
golang-1.10-linux language pack and to
go build our application:
set -eux cd gopath source /var/vcap/packages/golang-1.10-linux/bosh/compile.env go build -v github.com/cloudfoundry-community/simple-go-web-app mkdir $BOSH_INSTALL_TARGET/bin cp simple-go-web-app $BOSH_INSTALL_TARGET/bin
source .../compile.env is the second part of magic for language packs.
It does something different for each language pack, and for each base operating system. For the golang-release on linux, it sets up
$GOROOT and also sets
$GOPATH to the current directory.
So, in our
packaging script above, we first change to the base directory of our
$GOPATH and then run
source /var/vcap/packages/golang-1.10-linux/bosh/compile.env. We are now free to
go build to produce our linux binary
java language pack sets up
Finally, we copy the binary into the
$BOSH_INSTALL_TARGET folder. Anything in this folder is part of the compiled BOSH package.
Next, we need a BOSH job to run our packaged
bosh-gen job simple-go-web-app -d simple-go-web-app
This command will override some default files in a pre-created
jobs/simple-go-web-app directory. That's fine. Say yes to all prompts.
export BOSH_DEPLOYMENT=simple-go-web-app bosh create-release --force && \ bosh upload-release --rebase && \ bosh deploy manifests/simple-go-web-app.yml -o manifests/operators/dev.yml
Once the packages have been compiled and the
simple-go-web-app instance is running, you can ping your web app on the default job port
$ curl 10.244.0.2:8080 Hello world
Epilogue - CI Pipeline
To flesh out this example BOSH release, I've also added a CI pipeline, which publishes final releases, updates the base manifest
manifests/simple-go-web-app.yml with each version.
The CI pipeline, as well as, publishing compiled releases to S3, also creates a
use-compiled-releases.yml operator file.
To try it out:
bosh -d simple-go-web-app \ deploy <(curl -L https://raw.githubusercontent.com/cloudfoundry-community/simple-go-web-app-boshrelease/master/manifests/simple-go-web-app.yml) \ -o <(curl -L https://raw.githubusercontent.com/cloudfoundry-community/simple-go-web-app-boshrelease/master/manifests/operators/use-compiled-releases.yml)