canonical / operator-libs-linux

Linux helper libraries for the operator framework
Apache License 2.0
11 stars 40 forks source link

Feature request: Add support for parallel install of snaps #134

Open hemanthnakkina opened 2 months ago

hemanthnakkina commented 2 months ago

This is a feature request to add support for parallel install of snap.

This will be a minor change to retry getting snap info removing suffix instance key while getting snap information [2].

[1] https://snapcraft.io/docs/parallel-installs [2] https://github.com/canonical/operator-libs-linux/blob/a1aaa35135220d564f7a63854388b38752de09c4/lib/charms/operator_libs_linux/v2/snap.py#L907

benhoyt commented 2 months ago

Thanks @hemanthnakkina. Can you please be a bit more specific and detailed about what you're thinking this feature/API would look like?

hemanthnakkina commented 2 months ago

@benhoyt There are no API changes required for the lib to install a snap with <snap name>_<instance key> (the format used for snap in parallel install). However the lib currently breaks in maintaining SnapCache as snapcache tries to get information about the snap using the snap_name passed. Instead logic can be added in SnapCache to check the possibility of parallel install snap name format and retry getting snap info using actual snap name.

Changes might look like this

diff --git a/lib/charms/operator_libs_linux/v2/snap.py b/lib/charms/operator_libs_linux/v2/snap.py
index 9d09a78..979b593 100644
--- a/lib/charms/operator_libs_linux/v2/snap.py
+++ b/lib/charms/operator_libs_linux/v2/snap.py
@@ -904,10 +904,16 @@ class SnapCache(Mapping):
         Args:
             name: a string representing the name of the snap
         """
-        info = self._snap_client.get_snap_information(name)
+        try:
+            info = self._snap_client.get_snap_information(name)
+            name = info["name"]
+        except SnapAPIError:
+            # Check if the snap name is parallel install with instance key
+            snap_name = name.rsplit('_')[0]
+            info = self._snap_client.get_snap_information(snap_name)

         return Snap(
-            name=info["name"],
+            name=name,
             state=SnapState.Available,
             channel=info["channel"],
             revision=info["revision"],

There are no new parameters/functions exposed by the lib and so the current users are not impacted. The change will be compatible with existing version.

What do you think?

EDIT: The user of library (or charm) should provide the snap name with instance key rather than the lib generating instance key dynamically. In this way the onus is on charm to ensure sudo snap set system experimental.parallel-instances=true is set and maintain the snap instance name during the lifecycle of the charm.

benhoyt commented 1 month ago

Hi @hemanthnakkina, we'll do a bit more research on this and try to fix this early in the 25.04 cycle.