]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
portable: allow reattaching when one image has a version and the other does not
authorLuca Boccassi <bluca@debian.org>
Wed, 23 Mar 2022 21:29:04 +0000 (21:29 +0000)
committerLuca Boccassi <luca.boccassi@gmail.com>
Tue, 29 Mar 2022 13:02:48 +0000 (14:02 +0100)
A reattach might go from img.raw to img_0.1.raw or viceversa, but this is
not allowed right now as we try to match the full name.

Also take into account that running strcspn(a, '/') on an image name, without
leading path, will return the length of the full string, but the versions
might be different so they won't match, eg:

img_0.1.raw -> 12
img_0.1.1.raw -> 14

So adjust the check to take that into account, and skip it if we are not
dealing with directories

src/portable/portable.c
test/units/testsuite-29.sh

index 3051760d0b992e8e24fce7fd52a8c37cb1a393ed..155f731936ad21010111e624f83322f2981f31e3 100644 (file)
@@ -1429,17 +1429,28 @@ static bool marker_matches_images(const char *marker, const char *name_or_path,
                         size_t l;
 
                         /* We shall match against a path. Let's ignore any prefix here though, as often there are many ways to
-                        * reach the same file. However, in this mode, let's validate any file suffix. */
+                         * reach the same file. However, in this mode, let's validate any file suffix.
+                         * But also ensure that we don't fail if both components don't have a '/' at all
+                         * (strcspn returns the full length of the string in that case, which might not
+                         * match as the versions might differ). */
 
                         l = strcspn(a, "/");
                         b = last_path_component(*image_name_or_path);
 
-                        if (strcspn(b, "/") != l)
+                        if ((a[l] != '/') != !strchr(b, '/')) /* One is a directory, the other is not */
+                                return false;
+
+                        if (a[l] != 0 && strcspn(b, "/") != l)
                                 return false;
 
                         underscore = strchr(b, '_');
                         if (underscore)
                                 l = underscore - b;
+                        else { /* Either component could be versioned */
+                                underscore = strchr(a, '_');
+                                if (underscore)
+                                        l = underscore - a;
+                        }
 
                         if (!strneq(a, b, l))
                                 return false;
index c4e31b0a2d50710342ede8b6e73c32234010b0a7..47fd31b9b3a69042ca9f27ffdf8e2e6acb4743f2 100755 (executable)
@@ -88,6 +88,14 @@ systemctl is-active app1.service
 status="$(portablectl is-attached --extension app1 minimal_0)"
 [[ "${status}" == "running-runtime" ]]
 
+# Ensure that adding or removing a version to the image doesn't break reattaching
+cp /usr/share/app1.raw /tmp/app1_2.raw
+portablectl "${ARGS[@]}" reattach --now --runtime --extension /tmp/app1_2.raw /usr/share/minimal_1.raw app1
+
+systemctl is-active app1.service
+status="$(portablectl is-attached --extension app1_2 minimal_1)"
+[[ "${status}" == "running-runtime" ]]
+
 portablectl "${ARGS[@]}" reattach --now --runtime --extension /usr/share/app1.raw /usr/share/minimal_1.raw app1
 
 systemctl is-active app1.service