Subject: Why does apk fail to install packages with 0 size?

From: Wolf <[email-masked]>
Date: Thu, 8 Apr 2021 00:50:06 +0200

Hello,

To follow up on my original mail thread (apk not installing a file),
I've dived into apk's source code and managed to track the problem to:

src/database.c:
2920
2921         if (newpkg->installed_size != 0) {
2922                 r = apk_db_unpack_pkg(db, ipkg, (oldpkg != NULL),
2923                                       cb, cb_ctx, script_args);

Which I guess means that if installed size of the new package is zero, the
unpacking is skipped. That might sound reasonable, but leads to packages with
package function looking like:

package() {
        mkdir -p -- "$pkgdir"
        touch -- "$pkgdir/test-foo"
}

To be silently skipped with no errors nor warnings. That is highly confusing,
because there is not reason this should not work. For the time being, my
workaround is:

package() {
        mkdir -p -- "$pkgdir"
        echo >"$pkgdir/test-foo"
}

Which is bit sad result given how much time I've spent on this. :/

So, my question is: Is this behaviour intentional? If so, why? And if it
is not, what would be nice way to fix this? I can work on patch, however
I'm not sure what would be the best angle.

W.

-- 
There are only two hard things in Computer Science:
cache invalidation, naming things and off-by-one errors.

---

From: Ariadne Conill <[email-masked]>
Date: Wed, 7 Apr 2021 18:08:25 -0600 (MDT)

Hello,

> I'm not sure what would be the best angle.

I didn't think about the 0 installed-size at first.  Yes, this is 
intentional: packages with a 0 installed-size are treated as virtuals.

But, this can probably be fixed with a better design as part of apk-tools 
3.

Ariadne

---

From: Timo Teras <[email-masked]>
Date: Thu, 8 Apr 2021 09:41:48 +0300

Hi,

On Wed, 7 Apr 2021 18:08:25 -0600 (MDT)
Ariadne Conill <[email-masked]> wrote:

> > So, my question is: Is this behaviour intentional? If so, why? And
> > if it is not, what would be nice way to fix this? I can work on
> > patch, however I'm not sure what would be the best angle.  
> 

Same here. And yes, intentional. What normally happens is that 'abuild'
will stat all files disk-allocation size in the package and sum them to
installed size. Even zero files usually have "IO Blocks" size of 4k or
whatever is the smallest size on disk. But apparently there are file
systems where this can be zero. This does remind me of similar issue
earlier now. I think abuild should in this case still set non-zero
installed-size as the fix.

> But, this can probably be fixed with a better design as part of
> apk-tools 3.

Yes. The problem more connected to package generation. And this will be
automatically fixed in apk3 where package generation happens by apk
itself.

Timo

---

From: Wolf <[email-masked]>
Date: Fri, 9 Apr 2021 01:14:26 +0200

If there are only empty files in the pkgdir, on some filesystems
(discovered on btrfs), du might return 0 for the sum size of the files.
But apk-tools considers packages with size = 0 to be virtual and skips
extraction of any files contained.

To work around that (until it is resolved in apk-tools 3), settings the
size to 1 when it is zero AND some files are present should work fine.
---
 abuild.in | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/abuild.in b/abuild.in
index ebeb919..5a66866 100644
--- a/abuild.in
+++ b/abuild.in
@@ -1052,6 +1052,13 @@ prepare_metafiles() {
 	esac
 
 	local size=$(du -sk | awk '{print $1 * 1024}')
+	# If package contains only empty files, the size might be 0. But due to
+	# apk-tools 2 considering packages with size = 0 virtual, nothing is
+	# extracted. That will be solved in apk-tools 3. As a workaround we can
+	# set the size to 1 if any files are present.
+	if [ "$size" -eq 0 ] && [ -n "$(find . ! -name .)" ]; then
+		size=1
+	fi
 
 	if [ "$arch" != "$apkbuild_arch" ]; then
 		local msg="Split function set arch=\"$arch\" for $name, use subpackages=pkg:split:arch format instead"
-- 
2.31.0