Java Program that Purchases a Computer from Datacenter in London and Install Ubuntu using Linode API

Amazon AWS, Digital Ocean and Linode are well known cloud platform, infrastructure and other services providers. Below I explain how we can write a Java program that buys a computer from Linode London Datacenter, install Ubuntu OS and put it ON. Definitely, you can choose your datacenter of choice among following: Dallas, Fremont, Tokyo, London, Singapore, Frankfurt. I have selected London.

Linode provide RESTful services to create and manage different resources e.g. linux box aka Linode, node balancers, setting DNS, IPs, Backup, Storage and scalling system resources. Below program use Linode RESTful API via official wrapper Java API. Lets move step by step:

First of all, you must create an account at Linode.com. Login into your account, go to My Profile > API Keys and click on Create New API key. Note it down, we need it to make API calls.

Download the Linode official Java API from https://github.com/synapticloop/linode-api and add the linode-api.jar and runtime dependencies directly into youproject or setup maven dependencies.

Make LinodeApi object providing the API key.

LinodeApi linodeApi = new LinodeApi("Linode-API-key-here");
System.out.println("Fetching list of available datacenters ... \n");
List datacenterList = linodeApi.getAvailDatacenters().getDatacenters();

System.out.println("Datacenter ID, Location \n");
for (Datacenter datacenter : datacenterList) {
System.out.printf("%s \t %s\n", datacenter.getDatacenterId(), datacenter.getLocation());
}


It fetches list of datacenters. Please note, we later need one of the datacenter ID to specify where we want to put our system. The output shall look something like this:

Fetching list of available datacenters ... 

Datacenter ID, Location

2 Dallas, TX, USA
3 Fremont, CA, USA
4 Atlanta, GA, USA
6 Newark, NJ, USA
7 London, England, UK
8 Tokyo, JP
9 Singapore, SG
10 Frankfurt, DE
11 Tokyo 2, JP

Next we need to see what are different type of plans available to choose from. Let make an API call to fetch all the plans so that we can later choose one to create our virtual linux box. Here is the code chunk that retrieves all the available plans to choose from:

System.out.println("Different systems / plans you can buy from, fetching ... ");
List linodePlanList = linodeApi.getAvailLinodePlans().getLinodePlans();
System.out.printf("%4s%15s%6s%7s%10s%15s%15s\n", "ID", "Label", "Cores", "RAM", "Disk Size (GB)", "Hourly Price", "Monthly Price");
for (LinodePlan linodePlan : linodePlanList) {
System.out.printf("%4s%15s%6s%7s%10s%15s%15s\n",
linodePlan.getPlanId(),
linodePlan.getLabel(),
linodePlan.getNumCores(),
linodePlan.getRam(),
linodePlan.getDiskSize(),
linodePlan.getPriceHourly(),
linodePlan.getPriceMonthly());
}

Above code generates following output:

Different systems / plans you can buy from, fetching ... 

ID Label Cores RAM Disk (GB) Hourly Price Monthly Price
1 Linode 1024 1 1024 20 0.0075 5.0
2 Linode 2048 1 2048 30 0.015 10.0
3 Linode 4096 2 4096 48 0.03 20.0
4 Linode 8192 4 8192 96 0.06 40.0
5 Linode 12288 6 12288 192 0.12 80.0
6 Linode 24576 8 24576 384 0.24 160.0
7 Linode 49152 12 49152 768 0.48 320.0
8 Linode 65536 16 65536 1152 0.72 480.0
9 Linode 81920 20 81920 1536 0.96 640.0
10 Linode 16384 1 16384 20 0.09 60.0
11 Linode 32768 2 32768 40 0.18 120.0
12 Linode 61440 4 61440 90 0.36 240.0
13 Linode 102400 8 102400 200 0.72 480.0
14 Linode 204800 16 204800 340 1.44 960.0

You see, with each data, there is assciated ID. We need the ID later to specify the datacenter and plan. Lets first see the list of available kernels and distributions we can choose from. Then we would actually create a Linode.

List kernels = linodeApi.getAvailKernels().getKernels();
for (Kernel theKernel : kernels) {
System.out.println(theKernel.getKernelId() + " " + theKernel.getLabel() + " " + (theKernel.getIsKvm() ? "KVM" : "XEN"));
}

// get the distribution
Distribution distribution = null;
List distributions = linodeApi.getAvailDistributions().getDistributions();

System.out.println("ID | Distribution Label | Minimum Image Size | Instruction Set");
for (Distribution theDistribution : distributions) {
System.out.println(theDistribution.getDistributionId() + " " +
theDistribution.getLabel() + " " +
theDistribution.getMinimumImageSize() + " " +
(theDistribution.getIs64Bit()? "x64" : "32 Bit")) ;
}

So here is the list of available kernels to choose from and different distributions:

Fetching List of Available kernels ... 

137 Latest 32 bit (4.9.36-x86-linode104) KVM
257 4.9.15-x86-linode100 KVM
260 4.9.33-x86-linode102 KVM
262 4.9.36-x86-linode104 KVM
138 Latest 64 bit (4.9.36-x86_64-linode85) KVM
258 4.9.15-x86_64-linode81 KVM
259 4.9.33-x86_64-linode83 KVM
261 4.9.36-x86_64-linode85 KVM
92 pv-grub-x86_32 XEN
95 pv-grub-x86_64 XEN
61 Recovery - Finnix (kernel) KVM
.... (other kernels removed from list to keep to readable)

Here is the list of distribution to choose from:

ID | Label | Minimum Image Size |Type
148 Arch 2017.07.01 1800 x64
129 CentOS 7 1500 x64
157 CoreOS Container Linux 5000 x64
140 Debian 8 1024 x64
158 Debian 9 1100 x64
155 Fedora 25 1500 x64
159 Fedora 26 1500 x64
153 Gentoo 2017-07-12 9000 x64
160 OpenSUSE Leap 42.3 1900 x64
151 Slackware 14.2 1700 x64
146 Ubuntu 16.04 LTS 1024 x64
156 Ubuntu 17.04 1500 x64
127 CentOS 6.8 1024 x64
130 Debian 7 600 x64
149 Fedora 24 1024 x64
154 openSUSE Leap 42.2 1700 x64
87 Slackware 13.37 600 x64
117 Slackware 14.1 1000 x64
124 Ubuntu 14.04 LTS 1500 x64

So above was all the data we shall know about because we need to specify different type of information when creating our linode. There are 4 steps involved to create a Linode:

  1. Create a Linode specifying datacenter and plan
  2. Create a root disk specifying linode ID (retrieved from step 1), disk size, distribution ID and root password
  3. Create a Swap disk, there must be at least two disks created
  4. Create a configuration profile that you want to choose to boot linux e.g. kernel version etc.


Once the above 4 steps are done, we would be ready to boot our linux system. Lets see code to do each step, then I present the output that code produces:

// Create a Linode
System.out.println("Enter the Data Center ID and Plan ID from above List ? ");
long dataCenterID = scanner.nextLong(); // 7 for London --- see above list of data centers
long planID = scanner.nextLong(); // 1 for choose 1 GB RAM system ... see list of plans above
Long linodeId = linodeApi.getLinodeCreate(dataCenterID, planID).getLinodeId();
System.out.println("Your Linode is created with ID: " + linodeId);

//Create the root disk from the distribution

long distributionID = 146L; // 146 ID is for "Ubuntu 16.04 LTS 1024 x64"

System.out.println("Creating Root Disk with Ubuntu 16.04 LTS Distribution ... ");
Long diskId = linodeApi.getLinodeDiskCreateFromDistribution(
linodeID,
distributionID,
"devtrainings.com root disk",
5120L, "mypassword").getDiskId();
System.out.println("Root Disk created, with ID : " + diskId);

System.out.println("\nCreating SWAP Disk (two disks are required) ... ");
Long swapDiskId = linodeApi.getLinodeDiskCreate(
linodeID,
"devtrainings.com swap disk",
"swap", 256l).getDiskId();
System.out.println("Swap Disk created, with ID : " + swapDiskId);

Long kernelID = 138L; // 138 is is for Latest 64 bit (4.9.36-x86_64-linode85) KVM

System.out.println("Creating configuration for Latest 64 Bit Kernel ... ");

LinodeConfigResponse linodeConfigCreateResponse = linodeApi.getLinodeConfigCreate(
linodeID,
kernelID,
"devtrainings.com Ubuntu Config",
Long.toString(diskId) + "," + Long.toString(swapDiskId));
System.out.println("Configuration create. \n");

Here is the output:

Enter the Data Center ID and Plan ID from above List ? 
7
1

Your Linode is created with ID: 887987845

Creating Root Disk with Ubuntu 16.04 LTS Distribution ...
Root Disk created, with ID : 8787548752

Creating SWAP Disk (two disks are required) ...
Swap Disk created, with ID : 879878794

Creating configuration for Latest 64 Bit Kernel ...
Configuration created.

So far we have done following:
Buying a Linode in data center
Setting up Ubuntu on it

Now we are ready to start our Ubuntu system. Making call to boot system is little different from other calls. Above calls returned immediately but API call to boot the system returns with job ID. Which means, its a sync call. System would boot shortly after the calls returns. Now I present the code to boot the system:

System.out.println("Submitting job to boot our London Data center based Ubuntu Linux ... ");
LinodeJobResponse linodeBootResponse = linodeApi.getLinodeBoot(
linodeID,
linodeConfigCreateResponse.getConfigId());
System.out.println("Boot job submitted, Job ID = " + linodeBootResponse.getJobId());
System.out.println("System is booting ... ");

Output
Submitting job to boot our London Data center based Ubuntu Linux ... 
Boot job submitted, Job ID = 4875787849
System is booting ...

~~~~~~~~~~~~~~~~~

So our system is running now, its time to connect to our Ubuntu Linux using SSH. Here are the commands with output that confirms the system was running, as we connected with it and run ls command.

root@localhost:~# ssh root@1.1.1.1 (IP address changed for security reason, write your correct IP)
root@1.1.1.1's password:
Welcome to Ubuntu 16.04.2 LTS (GNU/Linux 4.9.36-x86_64-linode85 x86_64)
root@localhost:~# ls -l /
total 76
drwxr-xr-x 2 root root 4096 Mar 6 14:38 bin
drwxr-xr-x 3 root root 4096 Mar 6 14:39 boot
drwxr-xr-x 13 root root 13660 Jul 28 10:59 dev
drwxr-xr-x 88 root root 4096 Jul 28 10:59 etc
drwxr-xr-x 2 root root 4096 Jul 22 2016 home
lrwxrwxrwx 1 root root 32 Sep 9 2016 initrd.img -> boot/initrd.img-4.4.0-36-generic
drwxr-xr-x 19 root root 4096 Mar 6 14:38 lib
drwxr-xr-x 2 root root 4096 Mar 6 14:38 lib64
drwx------ 2 root root 16384 Jul 22 2016 lost+found
drwxr-xr-x 3 root root 4096 Jul 22 2016 media
drwxr-xr-x 2 root root 4096 Jul 22 2016 mnt
drwxr-xr-x 2 root root 4096 Jul 22 2016 opt
dr-xr-xr-x 131 root root 0 Jul 28 10:59 proc
drwx------ 3 root root 4096 Mar 7 20:34 root
drwxr-xr-x 16 root root 500 Jul 28 11:08 run
drwxr-xr-x 2 root root 4096 Mar 6 14:38 sbin
drwxr-xr-x 2 root root 4096 Jul 22 2016 srv
dr-xr-xr-x 13 root root 0 Jul 28 10:59 sys
drwxrwxrwt 8 root root 4096 Jul 28 11:05 tmp
drwxr-xr-x 10 root root 4096 Jul 22 2016 usr
drwxr-xr-x 11 root root 4096 Jul 22 2016 var
lrwxrwxrwx 1 root root 29 Sep 9 2016 vmlinuz -> boot/vmlinuz-4.4.0-36-generic
root@localhost:~#


Comments


  1. I'm amazed, I have to admit. Seldom do I come across a blog that's both equally educative and entertaining, and without a doubt, you have hit the nail on the head. The problem is something which too few men and women are speaking intelligently about. Now i'm very happy that I stumbled across this during my search for something regarding this. yahoo login mail

    ReplyDelete

Post a Comment