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
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 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
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:
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:
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.
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.
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.
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