Saturday, 2 August 2014

Deploying Advanced Golang Applications on IBM Bluemix

Introduction

Last time, we covered how to get a very simple hello world application running in Bluemix. This application required only Go's standard library. It was stateless because it didn't need to store any data or perform any kind of synchronization. There were no support files such as html or javascript. Also, it did not need to connect to any other services such as email.

This article attempts to fill in these gaps so that you can create more realistic Bluemix applications.

Third-Party Libraries

Sometimes, the Go standard library doesn't have everything you need. For instance, third-party libraries are often the only way to connect to a database. When you deploy your Bluemix application with the Go buildpack, it runs in "offline" mode. This means that it can't simply "go get" the libraries that you need. Instead, you must use the godep tool so that your application and all of its dependencies are uploaded directly from your laptop to Bluemix.

To install godep run "go get github.com/tools/godep." Change directory into your project and run "godep save." Godep requires an scm system in order to run the save operation. If you have not yet set up Git or you use an scm that it doesn't recognize you will need to run "git init" in your project before the save operation.

The next time you run "cf push" it should deploy your application along with its dependencies so that it compiles.

Setting Up MySQL

Data stored in memory is wiped every time your application restarts. Also, if you want to use multiple application instances they do not share the memory. You run into similar problems if you attempt to use the local filesystem. The solution is to use a database to store your application data.

Bluemix offers two different MySQL database systems at the time this article was written: MySQL and ClearDB. Both services provide an MySQL database instance and communicate the credentials to your applications via the VCAP_SERVICES environment variable. This is actually one of the best practices of a Twelve Factor Application, which says to decouple your services as much as possible using environment variables to bind them together.

Try creating one of these services using the Bluemix dashboard. When it prompts you for the application to bind, pick your Go application. The service is initialized and your application is restarted. Once it has restarted you can click on your Go application in the dashboard and see the services that are bound to it. Click on the "Show Credentials" link on the service and you will see a flyout with the JSON snippet that is in the environment variable for your application. You can see that the host, port, username and password are provided, which should be sufficient to establish a database connection in your application.

There are two popular MySQL drivers available for Go: MyMySQL and Go-MySQL-Driver. Learning how to use MySQL and the drivers is beyond the scope of this article. Pick the one that satisfies your requirements and install it using the "go get" tool (e.g. "go get github.com/ziutek/mymysql"). Add the necessary imports to your Go files. Run "godep save" to add the driver code to the godep repository in your project.

As mentioned earlier, all of the necessary connection information for MySQL can be found in the VCAP_SERVICES environment variable. Notice that when you checked your dashboard for the credentials they showed up in a json format. You need to parse out the particular information you need for MySQL using the json parser. Check out the following code snippet to see how I extracted the information from the ClearDB service. If you chose the MySQL service you will find that you can parse the details in a very similar way.

Now that you have the service and driver set up you can begin writing your code to populate and query your MySQL database. When you have finished writing your code you can deploy it by running "cf push" command.


Serving Static Content

Static content such as HTML files, templates and Javascript can be included in your package alongside your Go source code. It is automatically uploaded to Bluemix when you deploy. Also, when your Go program is executed the current working directory is the location where all of your files are uploaded. If you need to serve static content you can open the files using relative paths such as "static/index.html."

If you find that your static files cannot be opened by your application check your .cfignore files. They might be excluding files from being uploaded by cf push.

It is important to ensure that your static content handler will not provide access to sensitive files from your Bluemix application such as log files with sensitive passwords. The easiest way to do this is to disallow absolute paths and relative paths with ".." segments in it.

Sending Email

There is an email service in Bluemix called Sendgrid. It can be accessed using Go's standard net/smtp package. If you create a Sendgrid service and bind it to your application you will find that it provides the necessary host and credentials in the familiar VCAP_SERVICES environment variable along with the MySQL information. Sendgrid appears to use port 25, which is the default SMTP port. You will need to hard-code this port when using Go's smtp package.

Conclusion

Now that you can access a database, use third-party Go libraries, provide static content and send email you can create a full-featured application on Bluemix. Along the way you have learned about important patterns such as the VACP_SERVICES environment variable where the credentials for all of the bound services are communicated to your application. These patterns should enable you to interact with many of the services offered on BlueMix such as mobile and analytics should you require those capabilities.

For an example of a Go application that runs in Bluemix and uses many of the services covered in this article check out the "lunchsoccer" application published on IBM DevOps Services.

Thursday, 31 July 2014

Deploying Golang on IBM Bluemix

Introduction

Go language is a relatively new systems programming language. I have used it to develop a number of personal interest projects. When it came time to revamp our lunchtime sports signup sheet application I decided to give it a try in Go.

The application was originally hosted through Google App Engine. I could have easily rewritten it using App Engine's new Go SDK but I would prefer to avoid using the proprietary API's. Instead, I would like to use a hosting service that allows me to use the standard Go libraries for better portability in the future.

IBM recently announced the release of a PaaS cloud service called Bluemix. It allows you to write Node JS and Java web applications using the standard libraries. I don't have to manage my own operating system instances like I would have to do with various IaaS providers (eg. AWS, Digital Ocean). Instead, I can focus on writing my application.

IBM Bluemix is built using Cloud Foundry. Cloud Foundry has released an official Go language build pack that is compatible with Bluemix. This article will show you how to put all of the pieces together to get a simple application running.

Project Setup

Your Go project can be structured in the normal way from the "How to Write Go Code" article with a few extra files: .godir, Profile and manifest.yml.

The godir file should be at the top of your project. It contains a single line that provides the fully qualified package name of your application. This is important because you won't be pushing your entire GOPATH to Bluemix, just your project. It has no way to know the package name.



Your Procfile will tell Bluemix and the Go buildpack the executable that should run. This will generally be the name of the project directory. You need to add the prefix "web:" to make it work.



There is a special manifest.yml file that provides a number of parameters to deploy your application. Applications have names in Bluemix that allow you to distinguish them easily when looking at your dashboard or using the command-line tool. You can also provide the hostname of the application, which will determine the web address to access it (e.g. http://[myapp1].mybluemix.net). There are other parameters to let you fine tune your app such as the number of instances and RAM allocation. Finally, there are parameters such as the buildpack, path and domain, which you probably won't need to change.



Application Code

Your application is written like a typical Go web server application. You create a main function that will ultimately call "http.ListenAndServe." Unlike many of the examples on the internet you don't have a choice about the port number. You need to read an environment variable called "VCAP_APP_PORT" to get the port number to bind at runtime. You can get the value using "os.Getenv." I usually check for the environment variable and fall back to using a default port like this so that I can test the application on my laptop.


When writing your application it is vital to make it as robust as possible during startup up until the point where it begins listening for http connections. If your application panics or crashes in this period then it becomes difficult to figure out what went wrong. I recommend that you avoid panicking or logging fatal errors in your application. Instead, log those errors using log.Errorf() and log.Printf(). You can find those messages later after you deploy using the Bluemix dashboard.

Deploying Your Application

Most Go programmers work locally on their laptop using their preferred editor. Deployments to Bluemix can be made using the Cloud Foundry command-line tool once it is installed on your laptop. Bluemix is based on Cloud Foundry, so the CLI is compatible.

You can download the Cloud Foundry CLI using "go get github.com/cloudfoundry/cli." Go get will complain that there are no buildable Go source files. This project has a custom build script. Change directory to the src/github.com/cloudfoundry/cli directory in your GOPATH. Run the bin/build script to compile. Finally, move the "cf" binary from the "out" directory to the "bin" directory of your GOPATH. The CLI will be on your system path assuming you have followed the "How to Write Go Code" article linked above.

Once you have installed the cf tool you can log into Bluemix with "cf login." The API endpoint for Bluemix is "https://api.ng.bluemix.net" and you log in with your BlueMix credentials. It will prompt you for a "space" to push your applications. Spaces are a way of organizing your deployed applications. When you first created your Bluemix account it probably created a space called "dev." If you are unsure which space to use then try that one.

You are now ready to deploy your application to Bluemix! Change directory to your project and run "cf push." When the push is complete your application should be online and accessible from your web browser at http://myapp1.mybluemix.net (replace myapp1 with the name you chose for your application). Check your Bluemix dashboard and there should be a box for your application. You can use the dashboard to start/stop and check the logs among other things.

If you want to deploy new changes to your application then run "cf push" again. The CLI will take care of stopping/starting your application with your changes.

Conclusion

This article has covered the three main areas needed to get a simple Go application running on IBM Bluemix. There are a few special files that need to be included in your project. Your application is for the most part a standard Go web server application with extra environment variables and special logging and robustness concerns. You can deploy your application using the Cloud Foundry CLI tool on your laptop. Future articles will attempt to cover more advanced topics such as database connectivity, using third party libraries and sending automated emails.

If you are interested in looking at a full example of a Go Bluemix application check out my lunchsoccer project on IBM DevOps Services.

Special thanks to Michele Crudele and his developer works article for providing guidance on how to get started.

Tuesday, 6 May 2014

Building Go - First Steps

As I have mentioned in my previous posts, my goal is to add a new architecture (PowerPC) to the Go toolchain. If successful, you will be able to both compile and install the toolchain on a PowerPC machine. Also, you will be able to cross-compile PowerPC (ppc64) binaries using x86/arm machines. This is due in part to the multi-platform capabilities inherited from Plan 9.

Logically, each of the four fundamental tools in the toolchain (Assembler, Linker, C Compiler, Go Compiler) has some mixture of platform-neutral and platform-specific code. This is evident given the fact that there are platform-neutral directories (ld, cc, gc) as well as platform-specific ones (e.g. 5a, 5l, 5c, 5g). It is clear that that I need to create ppc64 equivalents (e.g. 9a, 9l, 9c, 9g).

At a very superficial level, ppc64 shares some similarities with arm. They are both considered RISC architectures. There are still some very large differences including the endianness and number of registers, but the arm code seems like a better place to start than with x86/amd64, which are much different. I copied the 5x directories to 9x as a starting point to get something compiling.

Running an initial build of the toolchain (using the "src/all.bash" script) falls flat on its face.
$ ./all.bash
# Building C bootstrap tool.
cmd/dist
go tool dist: unknown architecture: ppc64
This is not entirely unexpected. I did not declare the ppc64 architecture anywhere in the code and I have not mapped it to the chosen number '9.' The question is where to put the declaration and mapping. A good place to start is with the "cmd/dist" entry shown in the build log from the "all.bash" script.

The toolchain uses a special C program called 'dist' instead of make to compile the tools, which was quite unexpected. The build log doesn't show the command-line parameters and the dist command doesn't have any debugging symbols making it rather difficult to figure out what goes wrong. Let's fix that by making these changes to the 'make.bash' file:
make.bash:
${CC:-gcc} $mflag -g -O0 -Wall -Werror -o cmd/dist/dist -Icmd/dist "$DEFGOROOT" cmd/dist/*.c
...echo ./cmd/dist/dist bootstrap $buildall $GO_DISTFLAGS -v

./cmd/dist/dist bootstrap $buildall $GO_DISTFLAGS -v # builds go_bootstrap

After some careful debugging I discovered that the declarations should go in the cmd/dist/build.c and cmd/dist/unix.c files:
build.c:
// The known architecture letters.
static char *gochars = "56689";
// The known architectures.
static char *okgoarch[] = {
// same order as gochars
"arm",
"amd64",
"amd64p32",
"386",
"ppc64",
};
dist.c:
else if(contains(u.machine, "arm"))
gohostarch = "arm";
else if(contains(u.machine, "ppc64"))
gohostarch = "ppc64";


Now when I run the all.bash script it gets alot further along but ultimately fails due to missing dependencies. I will go over the problem and my solution in the next post.

Sunday, 4 May 2014

Origin of the Go toolchain

I will devote some time to presenting what I understand to be the origins of the toolchain. I think it helps to explain why the design looks like it does. Please take it with a grain of salt because I may not have the complete and accurate picture. I ask any experts out there to please point out any misunderstandings or inaccuracies.

The Go toolchain has a history that extends back to Plan 9, an operating system developed in Bell Labs starting 30 years ago and intended to be the successor to Unix. You need only to check the wikipedia article to see the resemblance between the Go mascot and the Plan 9 mascot. I could devote an entire post about Plan 9 alone. I encourage anyone with an understanding of Unix/Linux to give it a try in a Virtualbox image.

To make a long story short, Plan 9 is a distributed operating system that allows you to treat a collection of computers as one logical system. A system can be composed of nodes with different processor architectures (e.g. arm, powerpc, x86, mips). In order to support such a system there needs to be a platform independent programming language, ANSI C. Also, there needs to be a way to easily compile and distribute architecture-specific binaries.

It is for this reason that Plan 9 has a variety of C compilers that you can invoke. Each one compiles C code into a architecture-specific object file. The object files are linked together with the correct linker for the architecture to produce the final binary. This can be repeated for each architecture so that your program can run anywhere in the system. Plan 9's sophisticated union mounts are configured so that the '/bin' directory usually contains the binaries for the correct architecture for the current node making it transparent to most users.

Plan 9's compilers, linkers and assemblers use a two character naming convention. One example is the "8c" tool, which is the C compiler for x86. Similarly, "5l" is the Linker for ARM. I'm not certain in all cases how the first character is chosen. I found a table with the historical architectures in the C compiler documentation. When you want to refer to the tools in an architecture independent way there are two-letter names: cc (C compiler), ld (linker).

Getting back to the Go toolchain, it retains the naming convention with some additions. They have chosen the number '6' to represent the relatively new AMD64 (64-bit x86) architecture. Also, they have added the letter 'g' to represent the Go compiler (e.g. 8g for x86 Go compiler, gc for the general name). The Go tool hides much of these internals away with its high level commands but you can still find them the pkg/tool/archname directory of your installation.

Go toolchain also uses a unique family of high-level assembly languages originally devised in Plan 9. You can't generally copy assembly language snippets and embed them in your Go programs. For example, there are special move pseudo-instructions in place of the usual load/store that are common in some architectures, such as PowerPC. Also, there are certain addressing modes used in all of the assemblers.

Go has its own object file and archive file format based on Plan 9. Plan 9 existed before ELF so you'll find that even the Linux 'nm' tool is unable to parse the archive (*.a) files in your GOPATH/pkg directory. You will notice the same kinds of issues using any OS-specific tool on these files in Windows, Mac OS, Solaris and FreeBSD. Fortunately, Go provides its own 'nm' and 'objdump' tools to inspect object and archive files. In most cases, you can use OS tools to analyse the final executable because the Go linker eventually converts everything into the OS-specific format.

I'm going to stop here. I hope that this post has been useful, interesting and accurate.

Saturday, 3 May 2014

Introduction

Welcome to the Adventures on the Go blog. I am relatively new to the Go language. What better way to build a thorough understanding than to look at how the toolchain and compiler works?

The toolchain currently supports a number of popular architecture (x86, amd64 and arm) but lacks support for PowerPC. Also, the toolchain is largely undocumented, except for some old plan 9 documents from the more than 10 years ago. This seems like a good area to explore for a project.

Porting the toolchain to a new processor architecture will certainly be difficult to achieve, considering my lack of experience in compilers and linkers. I hope to document what I learn about the toolchain along the way so that it can help others who want to explore it. This is the central purpose of this blog. I hope that it is helpful.