IC-OS is an umbrella term for all the operating systems within the IC, including SetupOS, HostOS, GuestOS, and Boundary-guestOS.
-
SetupOS: Responsible for booting a new replica node and installing HostOS and GuestOS.
-
HostOS: The operating system that runs on the host machine. Its main responsibility is to launch and run the GuestOS in a virtual machine. In terms of its capabilities, it is intentionally limited by design to not perform any trusted capabilities.
-
GuestOS: The operating system that runs inside a virtual machine on the HostOS. The core IC protocol is executed within the GuestOS.
-
Boundary-GuestOS: The operating system that runs on boundary nodes. It contains all the services necessary to fulfill the two main tasks of the boundary nodes: (1) route ICP API requests to a healthy replica of the right subnet (
ic-boundary
); and (2) translate HTTP requests into ICP API requests to allow direct access to dapps from the browser (icx-proxy
).
For details on adding to and removing files from IC-OS builds, refer to the components/ documentation
All the IC-OS images can be built though Bazel.
Building IC-OS images locally requires environment configuration. The required packages are found in ic/gitlab-ci/container/Dockerfile.
In addition to these packages, Bazel must be installed.
As an alternative, the following script can be used to build the images in a container with the correct environment already configured:
./gitlab-ci/container/container-run.sh
Each image has its own build targets, which are variations of the image:
-
SetupOS:
prod
,dev
-
HostOS:
prod
,dev
-
GuestOS:
prod
,dev
,dev-malicious
-
BoundaryGuestOS:
prod
,dev
The difference between production and development images is that the console can be accessed on dev
images, but not on prod
images.
Note: The username and password for all IC-OS dev
images are set to root
Use the following command to build images:
$ bazel build //ic-os/{setupos,hostos,guestos,boundary-guestos}/envs/<TARGET>/...
All IC-OS image build outputs are stored under /ic/bazel-bin/ic-os/{setupos,hostos,guestos,boundary-guestos}/envs/<TARGET>
Example:
$ bazel build //ic-os/guestos/envs/dev/... # This will output a GuestOS image in /ic/bazel-bin/ic-os/guestos/envs/dev
IC-OS images are first created as docker images and then transformed into "bare-metal" or "virtual-metal" images that can be used outside containerization.
Rather than installing and relying on a full-blown upstream ISO image, the system is assembled based on a minimal Docker image with the required components added. This approach allows for a minimal, controlled, and well understood system - which is key for a secure platform.
Note
|
For a detailed overview of the build process, refer to the Bazel icos_build macro |
The main build stages are as follows:
The docker build process is split into two dockerfiles. This split is necessary to ensure a reproducible build.
Dockerfile.base
ic/ic-os/{setupos,hostos,guestos,boundary-guestos}/context/Dockerfile.base
-
The Dockerfile.base takes care of installing all upstream Ubuntu packages.
-
Because the versions of these packages can change at any given time (as updates are published regularly), in order to maintain build determinism, once a week, the CI pipeline builds a new base image for each OS. The result is published on the DFINITY public Docker Hub.
Dockerfile
ic/ic-os/{setupos,hostos,guestos,boundary-guestos}/context/Dockerfile
-
The Dockerfile builds off the published base image and takes care of configuring and assembling the main disk-image.
-
Any instruction in this file needs to be reproducible in itself.
The docker image is then transformed into a bootable "bare-metal" or "virtual-metal" VM image for use outside containerization (either in a VM or as a physical host operating system). The resulting image is minimal, with only a few systemd services running.
Note that all pre-configuration of the system is performed using docker utilities, and the system is actually also operational as a docker container. This means that some development and testing could be done on the docker image itself, but an actual VM image is still required for proper testing.
-
components/: This directory contains scripts and components that are copied to the target IC-OS.
-
For instructions on how to make changes to the OS, refer to the components/ documentation
-
-
bootloader/: This directory contains everything related to building EFI firmware and the GRUB bootloader image.
-
scripts/: This directory contains build and utility scripts for the IC-OS.
To add a new package to an IC-OS image you need to:
-
Update the list of packages to install in
ic/ic-os/{setupos,hostos,guestos,boundary-guestos}/context/packages.common
-
Commit the changes and wait for CI to publish the base image
-
-
Update the base image hash in
ic/ic-os/{setupos,hostos,guestos,boundary-guestos}/context/docker-base.<env>