User Tools

Site Tools


Turris OS compilation from source codes

Turris is an OpenWrt-based system with various tweaks and additional software that for example automatically updates the system or analyzes network traffic. The complete source codes for Turris OS are available from the git repository and binary versions of it can be compiled practically on any machine. Turris OS can be compiled on any PC. In production, the system is compiled automatically on Ubuntu and the following steps are verified for that system, but the compilation process should be similar on any other compatible system. The first step is to clone the Turris OS repository. That can be done via one of the following commands (the second command is for cloning from a mirror GitHub server):

git clone https://gitlab.labs.nic.cz/turris/openwrt.git
git clone https://github.com/CZ-NIC/turris-os.git

Preparing the development environment

The best way to guarantee a smooth compilation process is to use an identical environment to the one used in production. Best is to have a container with this environment, which will enable the separation of the main system from the system for compilation. There are two supported ways of doing this, either by using a tool called Vagrant or using Docker.

Vagrant

Vagrant is a tool for easy management of development environments. Scripts are available in the Turris OS repository, which allow the creation of this environment with just few commands. At the same time it ensures synchronization between the host system and development environment, so it is possible to work with sets of programs installed on the host system in terms of repository (for example with the favorite text editor) and all changes are immediately propagated to the otherwise isolated environment, which only shares a directory with the cloned repository and in which the system compilation is started.

First we install the Vagrant application. This can be done using a package manager (for example APT on Ubuntu/Debian), however, in some distributions only older versions are available, which miss various required functionalities so problems may occur. In such cases it is advisable to download the newest version from the official website.

While installing Vagrant, installation of the the plugin vagrant-lxc, which allows the use of LXC containers, is also required. The container make separation of the compilation environment from the host system easier without significantly compiling speed decrease. This plugin of course also requires support of LXC in the host system. Installation of this plugin and its dependencies can be done with these two commands (assuming that Vagrant is already installed):

sudo apt-get install lxc
vagrant plugin install vagrant-lxc

In the last step, you should create a symbolic link (or copy) to a file with a development environment definition and put it into the root directory with the cloned Turris OS repository:

ln -s vagrant/Vagrantfile

It is now possible to run an instance of the development environment. This can be done using the command vagrant up --provider=lxc (the option --provider=lxc is required for the first initialization only). This command comes in useful every time the installation is terminated (using vagrant halt or after the host system reboot). In those cases, where the development environment needs to be reinstalled or it needs to be completely removed, the command vagrant destroy can be used.

To access the development system the command vagrant ssh can be run in Turris repository directory. This opens up an SSH connection to the container with the development environment and it can now be used as normal system. The directory synchronized with the Turris OS repository is accessible through the path /openwrt.

Docker

Docker is in comparison with the Vagrant tool more widespread, and thus it is possible that it is already installed and configured on your system. The files needed to create Docker containers are located in the cloned Turris OS repository in the directory 'Docker'. The necessary files are the scripts: build-all and run and especially files describing Docker containers. The first step is to create containers. The script build-all contains five lines calling docker, which create five containers. Their names and meaning are the following:

  • base – basic system containing all the dependencies needed to build Turris OS. Source codes are cloned in the directory '/ home / build / openwrt' in the latest version of the 'test' branch (a branch which is now being developed).
  • omnia-toolchain – requires the base and builds on it. It is the place where the configuration for Turris Omnia is and it contains the compiled toolchain. Packages, however, are not compiled. This can be useful, if you need to adjust a single package only, not the whole system.
  • omnia – requires and is based on the omnia-toolchain. The container accommodates the basic system and the system for Turris Omnia. This container, however, not all of the packages are compiled (this would require a large amount of time).
  • turris-toolchain - requires and builds on the base. It has configurations for Turris 1.x and the compiled toolchain. The packages, however, are not compiled. This can be useful if you need to compile only one package, not the whole system.
  • turris - requires and builds on turris-toolchain. The container is designed for the basic system of Turris 1.x and so compilation should be quick. But even in this case, not all packages are compiled (that would require a large amount of time).

To save time and space you can remove the lines for the platform, which is not relevant to you. Then run the script build-all. This process may take hours, depending on the performance of the hardware on which the compilation runs and on which you are creating the containers.

After the containers are created, it is possible to access them using the Run script. This script requires the name of the container (e.g. './run Omnia') as the first argument. If no arguments are passed, it will attempt to attach to the container omnia-toolchain.

Beware! As far as the Docker is concerned, after the end of the container all changes are discarded if not set otherwise. Also unlike the Vagrant tools, Docker does not work with your original cloned repository.

In the following sections distinguish which container you chose to use. In case of base, you have to perform the procedure as described. For other Docker containers you do not need to update feeds and configuration settings, you can move straight to the compilation. In that case it is also not recommended to use compile_fw script because that first cleans the repository.

Installation without Vagrant environment

If you don't want to or can't use Vagrant on your system, then it is possible to install compilation dependencies directly onto the system. These dependencies can be found in the initialization script vagrant/vagrant_bootstrap.sh, which is run during the initial run of the Vagrant environment. In systems based on Debian the commands can mostly be used without change. In other systems, corresponding packages have to be installed. Table on OpenWrt wiki can be useful when searching for appropriate packages. The previously mentioned script also edits the URL for package download and optionally allows installation of additional arguments for the command make in the buildroot using the extension openwrt-bash-completion.

The last resort option is the use of a virtual system. This method is more demanding on resources (CPU and memory), but it is possible to apply in on a wide variety of systems, including Windows. Virtualization can be done using for example a freely distributed application VirtualBox. In that case, it is advisable to choose Ubuntu as the installed system, because then it is enough to clone the Turris OS repository and run the previously mentioned script and the development environment is ready.

Compiling Turris OS

Turris OS, or OpenWRT, consist of big amount of scripts. Multiple steps are required to build Turris OS such as configuration generation, feeds fetching (those contain additional packages outside of OpenWRT), feeds patching and more. Because of complexity of such task a compile_fw script was implemented in Turris OS. It automates all tasks required for Turris OS build.

Depending on target board board of your build you should use either compile_omnia_fw (for Turris Omnia) or compile_turris_fw (for Turris 1.x).

You can pass additional arguments to compile_fw script derivate and those are passed to make call of OpenWRT build. Suggested argument is -j$(nproc) to run build in parallel for faster builds.

In default, only minimal set of packages is build. This is not complete Turris OS but should be enough for example for new packages creation. This kind of build is used for development for faster build times, that is around half a hour or hour depending on hardware.

To build complete Turris OS and to generate medkit you have to set environment variable BUILD_ALL=y when you run compile_fw script derivate. You can do that by BUILD_ALL=y ./compile_omnia_fw (with compile_turris_fw for Turris 1.x). You have to use this build when you want to create your own medkit (archive with root file-system to be flashed to router). This build can take more than eight hours to complete depending on used hardware and it is prune to failure (caused by race conditions).

If you encounter problems with build then you can try to change -j value or you can just use -j1 to disable build in parallel. These problems are caused by race conditions in build and by hard to discover missing dependencies.

Troubleshooting

Insufficient space when creating the Docker container

Docker containers usually take up tens of gigabytes. If their creation failed because of insufficient space, then you should check, if you really have run out of space and clear it. If you however have enough space, then you might need to adjust the configuration of the Docker daemon with the use of these options --storage-opt dm.basesize=40G --storage-opt dm.loopmetadatasize=10G.

The resulting configuration should look something like this:

dockerd -H fd:// --storage-opt dm.basesize=40G --storage-opt dm.loopmetadatasize=10G

After this adjustment it is necessary to restart the Docker daemon and remove all generated files for the change to apply. The exact path of the files depends on your system, but it is usually /var/lib/docker.