Package manager opkg. Offline installation of packages in the root file system image

  • Tutorial
pinguin_packet_dry

Widely known in narrow circles, the lightweight package manager opkg has become widespread in embedded Linux for a reason . Opkg is used in many embedded distributions and projects, for example, in OpenEmbedded , Yocto Project , OpenWRT , Ångström , Arago Projectand some others. The manager is easy to use, the built-in help is quite enough for full-time work, and on the World Wide Web there are a lot of articles on how the ipk package itself is arranged (opkg works with this format): how to create it, how to install, etc., etc. . However, the vast majority of information is devoted to how to work on the system already installed on the target platform (target) in online mode, but the Embedded specifics imply that the image of the root file system and the kernel are prepared in advance on some instrumental platform (host) other than target. In other words, we assemble the kernel and file system on a working computer, pack it into an image, replicate the image to hardware. This article is about how to use the opkg manager install packages in the prepared rootfs image.


Rake and bike path


Many years ago, when I was an engineer at a small factory, when I launched Linux on the first board of my own production, using opkg, I installed all the required packages from a remote repository, configured all the applications, the head of the laboratory said: “Great! Now do the same on all devices in the party. " "Sure, not a problem!" I answered. The system is there, it is up and running. We copy all the files from the root to an external medium, then pack them into an image and enjoy life! At that time, I did not understand that during operation, the operating system performs a number of local settings, creates temporary files, configuration files, generates some keys, and at the first start it also executes initialization scripts. Although transferring files from one working system to another using a dull copy method from the media gave the result, but the effectiveness of this method very soon became doubtful for me. It is impossible to get a “clean” system in this way: the system remembers its previous life in another hardware body, and from time to time it is choked by phantom pains.
Another crazy idea
On target, mount an external drive with rootfs, chroot and install packages. I will not comment.

The next step for me was to understand the structure of the * .ipk package itself . Essentially, the ipk package is an archive that can be unpacked easily using the command:

ar -x *.ipk

As a result, we get:

 .
├── control.tar.gz
├── data.tar.gz
└── debian-binary 

The data.tar.gz archive contains files that should be placed in the root directory of the target.
The control.tar.gz archive contains utility files: a description file and scripts. The idea is simple: since ipk is just an archive with scripts, we can always unzip it with our hands to a directory with a file system, and then run (if necessary) scripts. Here are just all the dependencies of the package we will have to install manually as well.
And if addictions still have addictions? There is an idea, maybe write a script to automate the process? As often happens in the linux world, if a task arose before you, then most likely this task did not arise before you alone, and most likely you are not the first in this business.
I didn’t have to go far, in fact, the opkg package manager itself has such a mode when packages are installed in the inactive rootfs file system. At the same time, the architecture of the host machine (where opkg utilities are run) and the target machines can be excellent. This mode is called Offline mode . In this mode, opkg becomes a powerful cross-development tool.

Build opkg for host


To work in Offline mode, opkg must run on the host. For a long time, Ubuntu settled on my working computer (now it costs Ubuntu 14.04 LTS), on it we will build our toolkit. I could not find the repository with opkg for Ubuntu, so we are collecting a set of utilities from the sources.
You can get the source codes from the git repository of the Yocto Project :

    git clone git://git.yoctoproject.org/opkg.git
    cd opkg

For those who are scared of git
можно обойтись и без него. На момент написания статьи, актуальная версия утилиты – opkg-0.3.1. Качаем исходники с сайта и распаковываем:
tar xzf opkg-0.3.1.tar.gz
cd opkg-0.3.1/

In fact, setting up and compiling a project is done in a fairly standard way, but there are some nuances, and therefore everything is in order.
We launch:

./autogen.sh

Note: if you start ./autogen.shwith the parameter --clean, then all the work on the project configuration will be deleted.
After execution ./autogen.sh, a script appears in the source directory configure, it will configure the package, define and set system-dependent variables. As a result of the script, a Makefile is created. You can view all script options in the standard way:

./configure --help

We will collect the package for the current platform, because we skip the cross-compilation configuration options. We take care of the installation. By default, running the make installscript are scattered all useful files (binaries, scripts, documentation) on the root directory: /etc, /usr/localand that we completely useless. Are we not going to use opkg to configure packages on the current system? In addition, by installing the manager in the system folders, using the utilities will require superuser rights, in my opinion, this is unnecessary when setting up the embedded linux image. Scriptconfigure.shallows you to specify a prefix for the package installation directory. By specifying any working directory as a prefix, we will inform the installer where to install the package. If necessary, you can separately set the prefix for architecture-dependent (binaries and libraries) and architecture-independent (scripts and documentation) files.
With fantasy, I have always been rather weak, so for installation in the home directory we will create the opkg_offline directory.

mkdir ${HOME}/opkg_offline

Let's configure:

./configure --prefix=${HOME}/opkg_offline

If necessary, we deliver the required dependencies. So on my Ubuntu 14.04 for a successful assembly was required to deliver libarchive-dev, libcurl4-gnutls-dev, libssl-dev, libgpgme11-dev.
But how to do it?
sudo apt-get install libarchive-dev
sudo apt-get install libcurl4-gnutls-dev
sudo apt-get install libssl-dev
sudo apt-get install libgpgme11-dev


Compile and install opkg:

make  
make install  

As a result, in the opkg_offline directory we have:
opkg_offline
├── bin
│   ├── opkg
│   ├── opkg-check-config
│   └── opkg-key
├── lib
│   ├── libopkg.a
│   ├── libopkg.la
│   ├── libopkg.so -> libopkg.so.1.0.0
│   ├── libopkg.so.1 -> libopkg.so.1.0.0
│   ├── libopkg.so.1.0.0
│   └── pkgconfig
│       └── libopkg.pc
└── share
├── man
│   └── man1
│       ├── opkg.1
│       └── opkg-key.1
└── opkg
└── intercept
├── depmod
├── ldconfig
└── update-modules


The package manager is assembled and installed. The executables are located in the opkg_offline / bin directory. To work with them, you can specify a path in the PATH variable, either call export ( export) for each terminal session , or do as I do - go to the opkg_offline directory and run it directly ./bin/opkg.

Short course of anatomy


Let's briefly consider how the package manager works in standard mode. After executing the command opkg update, the utility reads the configuration files, which are located by default /etc/opkgand have the extension .conf. From these files, the system determines the type of architecture, for example armv5hf-vfp or armv5tehf-vfp (there can be several supported architectures, you can set a priority for each), a list of repositories, and some settings of the program itself. Next, for each repository, a type archive is downloaded from the list *_Packages.gz. Archives are placed in the directory by default var/cache/opkg/. After unpacking, the contents are placed invar/lib/opkg/lists. Each archive contains a text file with a list of packages in the repository. For each package, in addition to the name, the version, architecture, size, short description, license, and most importantly, dependencies are indicated. Based on these files, the package manager, upon request, can provide information about the required package, and when installing it, determine all the dependencies and resolve them.
The command opkg listwill display all the packages available for installation; the command opkg list-installedwill show only installed packages, the command opkg infowill show information about the specified package, and if it is installed, then the installation time.
To install the package, you should runopkg install packname. As a result, the required package from the repository will be downloaded to a temporary directory and distributed. All files from the data.tar.gz archive will go their places in rootfs, and on the basis of the contents of control.tar.gz var/lib/opkg/infoservice files will be created in the directory : packname.control- full information about the package, packname.list- list of directories that the files from data.tar shared .gz (this list should walk opkg when a package is removed), and script files, such as packname.postinst, packname.preinst, packname.prerm, packname.postrm, destination of which are clear from the title. Information about the installed package will be added to the file var/lib/opkg/statusin the form (example for the popular minicom ):

Package: minicom
Version: 2.6.2-r0.2Depends: libtinfo5 (>= 5.9), libc6 (>= 2.17)
Status: install ok installed
Architecture: armv7ahf-vfp-neon
Installed-Time: 1454529423

It is important to pay attention to Status. If the package was installed according to all the rules: all files are copied to their place, all scripts are executed, then the status will be Status: install ok installed. When working offline, all files will be copied, but the scripts will not be executed, such packages will be marked as Status: install ok unpacked.
For this case, opkg has a special mechanism for post-configuration of packages. It is launched by a team opkg configure <packname>. If you specify the name of a specific package, then scripts from var / lib / opkg / info will be executed for this package; if you omit the name, the manager will configure for all packages with a status Status: install ok unpacked. Thus, when installing packages on host in offline mode, when first loading the operating system on target, you should runopkg configure. You can entrust this with either a special script, or, if systemd is used , a special service.

Work with target rootfs


It is time to try the system in action. For example, install the minicom serial port terminal emulator.
To install packages, we need an unpacked image of the root file system of the target rootfs platform. Suppose that opkg manager is installed in rootfs, and etc/opkg* .conf configuration files exist in the directory . If it is not there, or for some reason we do not want to use the configuration of the rootfs, we can through the option to specify a configuration file to use: -f etc/opkg/opkg.conf. The path to the target file system is passed through the parameter --offline-root /path/to/rootfs.
Updating package lists:

bin/opkg update --offline-root /path/to/rootfs

We look through the list of available packages, look for minicom.

bin/opkg list --offline-root ~/board/rootfs/angstrom/rootfs-v2015.10 | grep minicom
minicom - 2.7-r0.0 - Text-based modem control and terminal emulation program  Minicom is a
minicom-dbg - 2.7-r0.0 - Text-based modem control and terminal emulation program - Debugging files
minicom-dev - 2.7-r0.0 - Text-based modem control and terminal emulation program - Development
minicom-doc - 2.7-r0.0 - Text-based modem control and terminal emulation program - Documentation

We look at the package information:

bin/opkg info minicom --offline-root ~/board/rootfs/angstrom/rootfs-v2015.10

    Package: minicom
    Version: 2.7-r0.0Depends: libtinfo5 (>= 5.9), libc6 (>= linaro-2.20)
    Status: unknown ok not-installed
    Section: console/network
    Architecture: armv7at2hf-vfp-neon
    Maintainer: Angstrom Developers <angstrom-distro-devel@linuxtogo.org>
    MD5Sum: e4d11b7277fbc1c7db6bbd97ac52ca2c
    Size: 79354
    Filename: minicom_2.7-r0.0_armv7at2hf-vfp-neon.ipk
    Description: Text-based modem control and terminal emulation program  Minicom is a text-based modem control and terminal emulation program for Unix-like operating systems

Install the package:

bin/opkg install minicom --offline-root ~/board/rootfs/angstrom/rootfs-v2015.10

An var/lib/opkgentry appeared in the file :

    Package: minicom
    Version: 2.7-r0.0Depends: libtinfo5 (>= 5.9), libc6 (>= linaro-2.20)
    Status: install user unpacked
    Architecture: armv7at2hf-vfp-neon
    Installed-Time: 1454594718

After the system was launched from the created image and the command worked opkg configure, the record in the file changed:

    Package: minicom
    Version: 2.7-r0.0Depends: libtinfo5 (>= 5.9), libc6 (>= linaro-2.20)
    Status: install user installed
    Architecture: armv7at2hf-vfp-neon
    Installed-Time: 1454594718

Since custom rootfs is for the embedded computer, the final image size matters. Therefore, I recommend that after all the necessary packages have been installed, delete the downloaded lists and clear the cache:

rm -rvf  ~/board/rootfs/angstrom/rootfs-v2015.10/var/cache/opkg/*  
rm -rvf  ~/board/rootfs/angstrom/rootfs-v2015.10/var/lib/opkg/lists/*

Note: this option --volatile-cachewill clear the cache automatically at the end of the work.

Instead of a conclusion


Despite the performance, Offline mode has some disadvantages. The fact is that the command only opkg configurelaunches for execution \*.postinst, but the issue of script execution remains unresolved \*.preinst. Due to the fact that \*.preinstit is quite rare in packages, it is acceptable for me to manually view the scripts and, if necessary, work them out the first time the target system is launched (special services for systemd). I would be grateful for the advice.

Read on the topic:



Also popular now: