The future is now: opkg vs apk

apk has replaced opkg in main branch SNAPSHOT builds

The apk switchover is an ongoing process, and still has several issues to resolve. If you do not wish to deal with the issues inherent in bleeding edge snapshots, then it is strongly suggested that you move to 24.10-SNAPHOT (https://downloads.openwrt.org/releases/24.10-SNAPSHOT/targets/).




@ynezz has graciously copied out the contents of the cheatsheet and put it in the wiki for all to edit. It is ready for you (yes, you) to work on fixing details and adding examples.

Before posting a new question, be sure to read:

https://openwrt.org/docs/guide-user/additional-software/opkg-to-apk-cheatsheet

He also created an outline for the reference page, which also needs your input:

https://openwrt.org/docs/guide-user/additional-software/apk




With @slh's posting of @aparcar's status report on the APK project (How can I tell opkg to prioritize a repo when a package if found in multiple repos? - #6 by slh), it seems like a good time to start talking about the user side of APK.


Note: APK is Alpine Linux's "Alpine Package Keeper" and has nothing to do with Android or other systems that may be using the same acronym.

              > everything else here moved to wiki <
26 Likes

Current status of the migration can be found here:

https://lists.openwrt.org/pipermail/openwrt-devel/2024-August/043098.html

10 Likes

Just let us know, how can we help.
Kr
K

I think Paul is looking for testers to grab a build from

https://downloads.staging.openwrt.org/snapshots/targets/

and see how it works. Since there's no support from any up the ASU-based upgrade tools for the staging builds, you'd need to manually install and configure one of the images from there.

2 Likes

@efahl
As the maintainer of 2 packages that call opkg within scripts to determine if other packages are installed, it seems prudent to do something soon to cater for incoming apk :wink:

To be clear, I am not talking about dependencies of the two packages (mesh11sd and opennds), but the availability of additional runtime functionality.

For example, do we have ip-full installed?

Now, opkg does not set an exit code, so a good way of checking is:

root@meshnode-8ecb:~# opkg list-installed | grep -w "ip-full" &>/dev/null;echo $?
0
root@meshnode-8ecb:~# 

If I look for ip-tiny:

root@meshnode-8ecb:~# opkg list-installed | grep -w "ip-tiny" &>/dev/null;echo $?
1
root@meshnode-8ecb:~# 

I so far have not had time to test one of the apk builds, so can't test with apk just now.

It is not clear whether apk sets exit codes and it is not clear what the output formats are like.

For example, does this work?:
apk list -I "ip-full"; echo $?

<Hmm, goes and checks his own packages' install scripts...>

It appears apk does the same as opkg in this regard, exit code is "ok" whenever the command executes, regardless of results.

On my alpine box, picked an installed package from the list:

$ apk list --installed zstd-libs ; echo $?
zstd-libs-1.5.6-r0 x86_64 {zstd} (BSD-3-Clause OR GPL-2.0-or-later) [installed]
0

$ apk list --installed blarg ; echo $?
0


When I wrote owut, I originally used the rpc-sys packagelist call, but found that lacking and started parsing the opkg database. I've since reverted to (mostly) rpc-sys, but it is missing some pieces that would help here specifically. I think we can replicate the is-installed functionality by using it with the package-manager-agnostic form:

$ ubus call rpc-sys packagelist '{"all":true}' | grep -qw 'tc-tiny' ; echo $?
0

$ ubus call rpc-sys packagelist '{"all":true}' | grep -qw 'blarg' ; echo $?
1

What I'd really like to do is add both is-installed and what-provides functionality to https://github.com/openwrt/rpcd/blob/master/sys.c#L184. (It is going to need to be reworked for the APK database in any case, so might as well pile on.)

I'm thinking something like this, with the count value added specifically to address use in shell scripts where it makes things a lot easier.

$ ubus call rpc-sys packagelist '{"installed": "tc-tiny"}'
{
  "count": 1,
  "packages": {
    "tc-tiny" : "version"
  }
}

$ ubus call rpc-sys packagelist '{"installed": "blarg"}'
{
  "count": 0,
  "packages": {
  }
}

Then we could do this (kinda verbose, clearly a function candidate):

$ ubus call rpc-sys packagelist '{"installed": "blarg"}' | jsonfilter -e '$.count'
0


Then for completeness (I have a use case in owut for this one, https://github.com/efahl/owut/issues/10):

$ ubus call rpc-sys packagelist '{"what-provides": "vim"}'
{
  "count": 1,
  "packages": {
    "vim-full" : "version"
  }
}

EDIT:

$ cat is-installed-rpc.sh
#!/bin/sh

not_installed()
{
    local pkg="$1"
    local ver="$(ubus call rpc-sys packagelist '{"all": true}' |
                 jsonfilter -q -e "$.packages['$pkg']")"
    [ -z "$ver" ]
}

if not_installed "$1"; then
    echo "You need to install $1"
else
    echo "$1 is already installed"
fi

$ ./is-installed-rpc.sh tc-tiny
tc-tiny is already installed

$ ./is-installed-rpc.sh blarg
You need to install blarg
1 Like

Errk! Ubus is all very well but to me it seems to be a level of abstraction that does very little other than turn simple tasks into complicated ones - or is it me being a grumpy old git :wink:

The package ip-full is a very good example of my problem.
Unlike dnsmasq that lists its compile options when you ask for its version, the various incarnations of the "ip utiliy" give no consistent indication.

If you have ip-full installed, what does apk list -I "ip-full" actually output?
Is it:
ip-6.3.0-r1 ......

or is it
ip-full-6.3.0-r1 ......
?

The opkg version:

root@meshnode-8ecb:~# opkg list-installed | grep ip-full
ip-full - 6.3.0-1
root@meshnode-8ecb:~#
1 Like

My alpine box doesn't have those packages, but the iproute2 package is probably sufficiently close for examples.

$ apk list 'iproute2*'
iproute2-6.9.0-r0 x86_64 {iproute2} (GPL-2.0-or-later) [installed]
iproute2-bash-completion-6.9.0-r0 x86_64 {iproute2} (GPL-2.0-or-later)
iproute2-dev-6.9.0-r0 x86_64 {iproute2} (GPL-2.0-or-later)
iproute2-doc-6.9.0-r0 x86_64 {iproute2} (GPL-2.0-or-later)
iproute2-minimal-6.9.0-r0 x86_64 {iproute2} (GPL-2.0-or-later) [installed]
iproute2-qos-0.5-r5 x86_64 {iproute2-qos} (GPL-2.0-only)
iproute2-qos-openrc-0.5-r5 x86_64 {iproute2-qos} (GPL-2.0-only)
iproute2-rdma-6.9.0-r0 x86_64 {iproute2} (GPL-2.0-or-later)
iproute2-ss-6.9.0-r0 x86_64 {iproute2} (GPL-2.0-or-later) [installed]
iproute2-tc-6.9.0-r0 x86_64 {iproute2} (GPL-2.0-or-later) [installed]

$ apk list --installed 'iproute2*'
iproute2-6.9.0-r0 x86_64 {iproute2} (GPL-2.0-or-later) [installed]
iproute2-minimal-6.9.0-r0 x86_64 {iproute2} (GPL-2.0-or-later) [installed]
iproute2-ss-6.9.0-r0 x86_64 {iproute2} (GPL-2.0-or-later) [installed]
iproute2-tc-6.9.0-r0 x86_64 {iproute2} (GPL-2.0-or-later) [installed]

$ apk list --installed 'iproute2'
iproute2-6.9.0-r0 x86_64 {iproute2} (GPL-2.0-or-later) [installed]

$ apk list --installed 'iproute2-minimal'
iproute2-minimal-6.9.0-r0 x86_64 {iproute2} (GPL-2.0-or-later) [installed]

(I see ubus here as a tool to hide the package manager, so if we change to apt or dnf in the future, I don't have to worry about my code working.)

Here I am at the bottom of a hole, furiously digging, trying to get out:

root@meshnode-8ecb:~# ubus call rpc-sys packagelist '{"installed": "blarg"}'
Command failed: Not found
root@meshnode-8ecb:~#

So to find out what packages I have installed, I first have to find out if I have the package I need to find out what packages I have installed....

1 Like

Sorry, installed and what-provides are my suggested additions to the existing packagelist code. Right now the only valid option for it is the all:bool value...

Mmm, none of this helps my problem really. I see I am going to have to install one of Paul's builds... and see what it actually does.
I will report back! Thanks Eric.

Rob

1 Like

@efahl
Well the image flashes ok and boots up....

This is what we have so far:

root@OpenWrt:~# apk
apk-tools 3.0.0_pre20240806, compiled for aarch64.

usage: apk [<OPTIONS>...] COMMAND [<ARGUMENTS>...]

Package installation and removal:
  add        Add or modify constraints in WORLD and commit changes
  del        Remove constraints from WORLD and commit changes

System maintenance:
  fix        Fix, reinstall or upgrade packages without modifying WORLD
  update     Update repository indexes
  upgrade    Install upgrades available from repositories
  cache      Manage the local package cache

Querying package information:
  info       Give detailed information about packages or repositories
  list       List packages matching a pattern or other criteria
  dot        Render dependencies as graphviz graphs
  policy     Show repository policy for packages
  search     Search for packages by name or description

Repository maintenance:
  index      Create repository index file from packages
  fetch      Download packages from repositories to a local directory
  manifest   Show checksums of package contents
  verify     Verify package integrity and signature

Miscellaneous:
  audit      Audit system for changes
  stats      Show statistics about repositories and installations
  version    Compare package versions or perform tests on version strings

This apk has coffee making abilities.
For more information: man 8 apk
root@OpenWrt:~# 

But:

root@OpenWrt:~# apk update
fetch https://downloads.openwrt.org/snapshots/targets/mediatek/filogic/packages/packages.adb
WARNING: updating and opening https://downloads.openwrt.org/snapshots/targets/mediatek/filogic/packages/packages.adb: remote server returned error (try 'apk update')
fetch https://downloads.openwrt.org/snapshots/packages/aarch64_cortex-a53/base/packages.adb
WARNING: updating and opening https://downloads.openwrt.org/snapshots/packages/aarch64_cortex-a53/base/packages.adb: remote server returned error (try 'apk update')
fetch https://downloads.openwrt.org/snapshots/targets/mediatek/filogic/kmods/6.6.35-1-f492dffe00c0a7786964bab6d7e76015/packages.adb
WARNING: updating and opening https://downloads.openwrt.org/snapshots/targets/mediatek/filogic/kmods/6.6.35-1-f492dffe00c0a7786964bab6d7e76015/packages.adb: remote server returned error (try 'apk update')
fetch https://downloads.openwrt.org/snapshots/packages/aarch64_cortex-a53/luci/packages.adb
WARNING: updating and opening https://downloads.openwrt.org/snapshots/packages/aarch64_cortex-a53/luci/packages.adb: remote server returned error (try 'apk update')
fetch https://downloads.openwrt.org/snapshots/packages/aarch64_cortex-a53/packages/packages.adb
WARNING: updating and opening https://downloads.openwrt.org/snapshots/packages/aarch64_cortex-a53/packages/packages.adb: remote server returned error (try 'apk update')
fetch https://downloads.openwrt.org/snapshots/packages/aarch64_cortex-a53/routing/packages.adb
WARNING: updating and opening https://downloads.openwrt.org/snapshots/packages/aarch64_cortex-a53/routing/packages.adb: remote server returned error (try 'apk update')
fetch https://downloads.openwrt.org/snapshots/packages/aarch64_cortex-a53/telephony/packages.adb
WARNING: updating and opening https://downloads.openwrt.org/snapshots/packages/aarch64_cortex-a53/telephony/packages.adb: remote server returned error (try 'apk update')
7 unavailable, 0 stale; 133 distinct packages available
root@OpenWrt:~#

Failed at the first step...
I know I can work round this, but the whole point is to test apk, at least I thought it was. Time is limited....

@efahl
I suppose it is easy enough to fix:

root@OpenWrt:/tmp# cat /etc/apk/repositories
https://downloads.openwrt.org/snapshots/targets/mediatek/filogic/packages/packages.adb
https://downloads.openwrt.org/snapshots/packages/aarch64_cortex-a53/base/packages.adb
https://downloads.openwrt.org/snapshots/targets/mediatek/filogic/kmods/6.6.35-1-f492dffe00c0a7786964bab6d7e76015/packages.adb
https://downloads.openwrt.org/snapshots/packages/aarch64_cortex-a53/luci/packages.adb
https://downloads.openwrt.org/snapshots/packages/aarch64_cortex-a53/packages/packages.adb
https://downloads.openwrt.org/snapshots/packages/aarch64_cortex-a53/routing/packages.adb
https://downloads.openwrt.org/snapshots/packages/aarch64_cortex-a53/telephony/packages.adb
root@OpenWrt:/tmp# 

Edit: Maybe not so easy.....

Moving on:
My packages also want to find out what wpad package is installed for example for owe support.

So:

root@OpenWrt:/tmp# 
root@OpenWrt:/tmp# apk list -I wpad* 2>/dev/null  | grep -w "wpad-mbedtls"; echo $? 
1
root@OpenWrt:/tmp#

This works.

Compare with:

root@OpenWrt:/tmp# apk list -I wpad* 2>/dev/null  | grep -w "wpad-basic-mbedtls"; echo $? 
wpad-basic-mbedtls-2024.03.09~695277a5-r2 aarch64_cortex-a53 {feeds/base/network/services/hostapd} (BSD-3-Clause) [installed]
0
root@OpenWrt:/tmp#

I guess this satisfies my requirement :smiley:

@aparcar, what's the state of the APK package feed builds in the staging area?

  1. In the installed firmware, it looks like the feeds file for the APK staging builds need to be pointed to that staging area, i.e., in /etc/apk/repositories:
    downloads.openwrt.org

    downloads.staging.openwrt.org

  2. But over on the staging server there are no packages anywhere but in the target package areas. The server has a file system link from
    https://downloads.staging.openwrt.org/snapshots/packages/ to
    https://downloads.staging.openwrt.org/packages-main/
    but that latter is empty, where I expected to see all the arch-specific directories there. (In the non-staging downloads, packages is not a link...)

The downloads.staging.openwrt.org is controlled by @ynezz who is currently OOO. In the meantime I started my own buildbot instance. Please use it instead, it also comes with packages for multiple architectures:

I mentioned it on the mailing list some time ago: https://www.mail-archive.com/openwrt-devel@lists.openwrt.org/msg66485.html

Since the package builds take more time, I run them manually. If you want to test for a specific architecture please ping me and I start a build. Please refrain to ask for daily builds, the staging infrastructure is not meant for that.

4 Likes

aarch64_cortex-a53 would be much appreciated if possible.

It might be good for the documentation to clarify that the apk in this context is not related to the Android app package format.

3 Likes

Thanks, I didn't even realize that existed. I'll update the intro above.

2 Likes

@bluewavenet Rob, the issue calling opkg to find out the package information is that it didn't quite work for me for either in Makefile post-install or in uci-defaults or during a service start when initiated by the opkg install command, can't exactly recall when it failed, but it did, so at some point I was also parsing the opkg file just like @efahl. So to me, the ubus call was a welcome change.

@aparcar Paul, will the ubus call rpc-sys packagelist work in 24.xx with either opkg or apk package managers or will it only be included with apk?

For my particular application I need my package to be able to find out, at run time, reliably, if another package, or list of packages, is installed.
For example do we have a full version, mesh version or basic version of wpad (for, in the same order, owe support, mesh encryption support or unencrypted mesh).
Now I need to do this with either an "opkg" system or an "apk" system (and not just for wpad, other packages too).

At least for all the packages mesh11sd needs to check for at run time, the following fairly simple script does the job:

is_installed() {
	# Check if a package is installed
	package="$1"
	is_opkg=$(type "opkg" &> /dev/null; echo $?)
	is_apk=$(type "apk" &> /dev/null; echo $?)

	if [ -z "$package" ]; then
		exitcode=2
	elif [ "$is_opkg" -eq 0 ]; then
		matches=$(opkg list-installed | grep -w "$package"" ")
		urlencode "$matches"; encmatches="$urlencoded"
		urlencode "$package"; encpackage="$urlencoded"
		exitcode=$(echo "$encmatches" | grep -w -q "$encpackage"; echo $?)
	elif [ "$is_apk" -eq 0 ]; then
		exitcode=$(apk list -I "$package" 2>/dev/null  | grep -w -q "$package"; echo $?)
	else
		exitcode=127
	fi
}

urlencode() {
	entitylist="
		s/%/%25/g
		s/\s/%20/g
		s/\"/%22/g
		s/-/%2D/g
		s/:/%3A/g
		s/>/%3E/g
		s/</%3C/g
		s/'/%27/g
		s/\`/%60/g
	"
	local buffer="$1"

	for entity in $entitylist; do
		urlencoded=$(echo "$buffer" | sed "$entity")
		buffer=$urlencoded
	done

	urlencoded=$(echo "$buffer" | awk '{ gsub(/\$/, "\\%24"); print }')
}

This tested in 24.xx and @aparcar apk test images.

Edit: Now merged into the mesh11sd package:

1 Like