How bootrino works

High level overview of how bootrino netboots

  • bootrino takes advantage of the fact that all cloud computing platforms run essentially the same version of Ubuntu
  • bootrino boots Ubuntu and passes in a startup script, along with a list of URLs which point to bootrino.sh shell scripts
  • the bootrino startup script wipes the Ubuntu operating system
  • the bootrino startup script downloads a new Run-From-RAM operating system from the web and installs it
  • each bootrino.sh shell script is run in sequence until all finished

Detailed description of how bootrino netboots

  • User visits http://console.bootrino.com
  • User creates an account and signs in
  • User sets up credentials in the cloud account which give access to start and control virtual machines
  • User configures http://console.bootrino.com with their cloud credentials
  • User enters the URL of a bootrino.sh script in the bootrino URL bar
  • console.bootrino.com loads the bootrino.sh via HTTP and displays it to the user
  • User presses “launch instance” which adds the bootrino.sh URL to a sequence of bootrinos to be started.
  • User chooses the cloud to run on / region / instance type and hits “launch instance”.
  • A bootrino.sh has a “launchtargets.json” data structure that defines which AMI/instance ID it should start on, for each instance type/region/cloud type combination (AWS, GCE or DO). This is how bootrino knows to start Ubuntu 16 on the cloud and region that the user chooses to launch on.
  • via JavaScript, console.bootrino.com instructs the cloud to launch an Ubuntu 16 instance and passes an initial startup script via userdata along with an array of the bootrino URLs to be run in sequence.
  • The Ubuntu machine boots
  • The Ubuntu machine executes the startup script
  • The startup script creates a /bootrino directory and copies /etc/network in to it. It does this because the networking information may be useful later in the process, so it is retained because the rest of the Ubuntu operating system will be deleted.
  • The startup script downloads creates a /bootrino/sequence directory and downloads each bootrino.sh shell script into it under a number corresponding to its position in the sequence
  • The startup script creates a “nextbootrinotorun” file which contains “0”, which is the first bootrino.sh script to be run
  • bootrino.sh script number 0 is always the same script, and it is always run prior to any user selected bootrino.sh scripts
  • bootrino.sh script number 0 downloads a new operating system (Tiny Core Linux) and puts it into the /boot directory
  • bootrino.sh script number 0 packs the bootrino directory up into an initramfs which it copies into the boot directory. This initramfs is include in the grub.cfg which ensures it will be mounted into Tiny Core’s file system when it boots.
  • bootrino.sh script number 0 replaces Ubuntus grub.cfg with a new grub.cfg which will boot Tiny Core Linux
  • bootrino.sh script number 0 reboots the machine
  • The machine boots up, this time not under Ubuntu, but under Tiny Core Linux, which runs purely from RAM
  • The initramfs that Tiny Core Linux was booted with includes a /opt/bootlocal.sh script, which is the startup script for Tiny Core
  • bootlocal.sh runs /bootrino/runnextbootrino.sh which runs the next bootrino in the sequence, which is number 1
  • The main hard disk may now be cleanly formatted because it is not being used by the operating system (it is not possible to reliabily format the hard disk of a running Ubuntu OS)
  • bootrino.sh script number 1 formats the hard disk
  • bootrino.sh script number 1 downloads & installs Tiny Core onto the clean disk
  • bootrino.sh script number 1 copies the /bootrino directory back onto the disk
  • bootrino.sh script number 1 reboots the machine again
  • The system is now in the state that we want - the old operating system/hard disk has been wiped clean and a Run-From-RAM OS is the only thing installed
  • Tiny Core’s bootlocal.sh runs /bootrino/runnextbootrino.sh which runs the next bootrino in the sequence, which is number 2 - the first user bootrino to run
  • It is the responsibility of each bootrino.sh shell script to ensure it chains on to the next bootrino.sh, if a next bootrino is defined. If the bootrino does not run the next in chain then the chain of bootrino execution stops.
  • What happens from here is entirely up to the bootrino.sh script. It might run some code, or install some software, or it might replace the operating system with another.
  • End

What is a bootrino.sh shell script?

  • the ultimate purpose of bootrino is so bootrino.sh shell scripts scripts can be loaded from HTTP servers and run by cloud based Run-From-RAM operating systems
  • a bootrino.sh shell script is any file whose filename ends with “bootrino.sh”
  • a bootrino.sh shell script is an ordinary shell script
  • examples: postgres.bootrino.sh foo.bootrino.sh alpine.bootrino.sh
  • bootrino.sh shell scripts can be put on any HTTP server
  • bootrino.sh shell scripts are loaded into http://console.bootrino.com when the user enters the URL location into the http://console.bootrino.com navigation bar
  • a bootrino.sh shell script includes a section of JSON with metadata about the script
  • the JSON metadata of a bootrino.sh script is displayed in http://console.bootrino.com
  • the JSON metadata has no special purposes apart from display to the user in http://console.bootrino.com
  • apart from supportedCloudTypes and launchTargetsURL, the JSON metadata fields have no special purposes apart from display to the user in http://console.bootrino.com
  • see below for a description of supportedCloudTypes and launchTargetsURL
  • the JSON data MUST start precisely with:
read BOOTRINOJSON <<"BOOTRINOJSONMARKER"
  • the JSON data MUST end precisely with:
BOOTRINOJSONMARKER
  • Here is an example of an extremely minimal bootrino.sh shell script
#!/usr/bin/ash
read BOOTRINOJSON <<"BOOTRINOJSONMARKER"
{
  "name": "Tiny Core 64 Python one line web server",
  "version": "0.0.1",
  "versionDate": "2017-11-27T09:00:00Z",
  "description": "Tiny Core 64 Python one line web server",
  "options": "",
  "supportedCloudTypes": [],
  "logoURL": "https://raw.githubusercontent.com/bootrino/bootrinos/master/tinycore_ssh_nginx/tiny-core-linux-7-logo.png",
  "readmeURL": "https://raw.githubusercontent.com/bootrino/bootrinos/master/tinycore_onelinewebserver_python/README.md",
  "launchTargetsURL": "https://raw.githubusercontent.com/bootrino/launchtargets/master/defaultLaunchTargetsLatest.json",
  "websiteURL": "https://github.com/bootrino/tinycore_onelinewebserver_python",
  "author": {
    "url": "https://www.github.com/bootrino",
    "email": "bootrino@gmail.com"
  },
  "tags": [
    "linux",
    "runfromram",
    "tinycore",
    "python"
  ]
}
BOOTRINOJSONMARKER
cd /opt
echo 'helloworld Python bootrino one line web server' > index.html
sudo python3 -m http.server 80 &

What is launchTargetsURL?

  • bootrino needs to be able to launch the same Ubuntu 16 operating system image on any cloud, any region and any instance type.
  • so when a user launches a bootrino, to find the correct Ubuntu image ID for this combination of cloud/region/instance type, there is a simple JSON structure that allows us to look up the correct Ubuntu image ID to launch
  • this JSON structure can be loaded from any URL but in the vast majority of cases it will always come from the same place, which is:
https://raw.githubusercontent.com/bootrino/launchtargets/master/defaultLaunchTargetsLatest.json
  • there may be circumstances under which for some reason someone wants to boot with something other than Ubuntu 16, but for all purposes that we can forsee, the launchTargetsURL should never need to vary from the URL shown here
  • the URL is specified as “launchTargetsURL” in the bootrino.sh file (see above)
"launchTargetsURL": "https://raw.githubusercontent.com/bootrino/launchtargets/master/defaultLaunchTargetsLatest.json",
  • this is the contents of the launchTargets JSON URL:
{
  "amazonwebservices": [
    {
      "region": "ap-northeast-1",
      "imageId": "ami-c317aaa5",
      "instanceType": "hvm",
      "name": "Ubuntu 17.10 (64bit)"
    },
    {
      "region": "ap-northeast-2",
      "imageId": "ami-eb69ce85",
      "instanceType": "hvm",
      "name": "Ubuntu 17.10 (64bit)"
    },
    {
      "region": "ap-south-1",
      "imageId": "ami-2e064841",
      "instanceType": "hvm",
      "name": "Ubuntu 17.10 (64bit)"
    },
    {
      "region": "ap-southeast-1",
      "imageId": "ami-685a0c0b",
      "instanceType": "hvm",
      "name": "Ubuntu 17.10 (64bit)"
    },
    {
      "region": "ap-southeast-2",
      "imageId": "ami-b4e40ed6",
      "instanceType": "hvm",
      "name": "Ubuntu 17.10 (64bit)"
    },
    {
      "region": "eu-central-1",
      "imageId": "ami-565cde39",
      "instanceType": "hvm",
      "name": "Ubuntu 17.10 (64bit)"
    },
    {
      "region": "eu-west-1",
      "imageId": "ami-1b2c9b62",
      "instanceType": "hvm",
      "name": "Ubuntu 17.10 (64bit)"
    },
    {
      "region": "sa-east-1",
      "imageId": "ami-48aaef24",
      "instanceType": "hvm",
      "name": "Ubuntu 17.10 (64bit)"
    },
    {
      "region": "us-east-1",
      "imageId": "ami-534bc129",
      "instanceType": "hvm",
      "name": "Ubuntu 17.10 (64bit)"
    },
    {
      "region": "us-east-2",
      "imageId": "ami-27c2ec42",
      "instanceType": "hvm",
      "name": "Ubuntu 17.10 (64bit)"
    },
    {
      "region": "us-west-1",
      "imageId": "ami-bfc6fedf",
      "instanceType": "hvm",
      "name": "Ubuntu 17.10 (64bit)"
    },
    {
      "region": "us-west-2",
      "imageId": "ami-599c4021",
      "instanceType": "hvm",
      "name": "Ubuntu 17.10 (64bit)"
    },
    {
      "region": "eu-west-2",
      "imageId": "ami-b9f1eedd",
      "instanceType": "hvm",
      "name": "Ubuntu 17.10 (64bit)"
    },
    {
      "region": "ca-central-1",
      "imageId": "ami-63833807",
      "instanceType": "hvm",
      "name": "Ubuntu 17.10 (64bit)"
    },
    {
      "region": "ca-central-1",
      "imageId": "ami-63833807",
      "instanceType": "hvm",
      "name": "Ubuntu 17.10 (64bit)"
    }
  ],
  "digitalocean": [
    {
      "imageId": "ubuntu-17-10-x64",
      "instanceType": "hvm",
      "name": "Ubuntu 17.10 (64bit)"
    }
  ],
  "googlecomputeengine": [
    {
      "imageId": "projects/ubuntu-os-cloud/global/images/ubuntu-1710-artful-v20171122",
      "instanceType": "hvm",
      "name": "Ubuntu 17.10 (64bit)"
    }
  ]
}