← Back to team overview

desktop-snappers team mailing list archive

[Merge] ~nteodosio/thunderbird:beta into ~desktop-snappers/thunderbird/+git/snap:beta

 

Nathan Teodosio has proposed merging ~nteodosio/thunderbird:beta into ~desktop-snappers/thunderbird/+git/snap:beta.

Requested reviews:
  Desktop Snappers Team (desktop-snappers)

For more details, see:
https://code.launchpad.net/~nteodosio/thunderbird/+git/thunderbird/+merge/426200
-- 
Your team Desktop Snappers Team is requested to review the proposed merge of ~nteodosio/thunderbird:beta into ~desktop-snappers/thunderbird/+git/snap:beta.
diff --git a/patch-default-profile.py b/patch-default-profile.py
new file mode 100755
index 0000000..7516281
--- /dev/null
+++ b/patch-default-profile.py
@@ -0,0 +1,76 @@
+#!/usr/bin/python3
+
+import configparser
+import os.path
+import sys
+
+
+# Mozilla products, when not packaged as a snap, use dedicated profiles per
+# installation by default, unless instructed otherwise (legacy mode). See
+# https://support.mozilla.org/en-US/kb/understanding-depth-profile-installation
+# for details.
+# We want to import existing profiles from a package of Firefox typically
+# installed in a well-known location. The following is a list of hashes for
+# such well-known locations, in descending order of popularity/likeliness
+# on distributions compatible with snaps:
+KNOWN_INSTALL_HASHES = [
+    'FDC34C9F024745EB',  # /usr/lib/thunderbird (Debian, Ubuntu, Arch)
+    '3DDF446CE6CB1A45',  # /usr/lib64/thunderbird (Fedora)
+    '9238613B8C3D2579',  # /opt/thunderbird (Gentoo thunderbird-bin)
+]
+
+
+def _patch_imported_profiles(profiles_file):
+    profiles = configparser.RawConfigParser()
+    profiles.optionxform = lambda option: option
+    profiles.read(profiles_file)
+
+    known_install = False
+    for known_hash in KNOWN_INSTALL_HASHES:
+        install_section = 'Install{}'.format(known_hash)
+        if install_section in profiles:
+            known_install = True
+            break
+    if not known_install:
+        return
+
+    try:
+        profile_path = profiles.get(install_section, 'Default')
+    except configparser.NoOptionError:
+        return
+    if not profile_path:
+        return
+    print('Found default profile: {}'.format(profile_path))
+
+    for section in profiles:
+        if section.startswith('Profile'):
+            try:
+                path = profiles.get(section, 'Path')
+            except configparser.NoOptionError:
+                continue
+            else:
+                if path == profile_path:
+                    # We found the section for the default profile,
+                    # explicitly mark it as such …
+                    profiles.set(section, 'Default', '1')
+                    # … and remove the default marker from any other profile
+                    # that might have had it.
+                    for other_section in profiles:
+                        if other_section.startswith('Profile') and \
+                                other_section != section:
+                            profiles.remove_option(other_section, 'Default')
+                    # Delete the Install section as it is meaningless
+                    # (and unused) in legacy mode.
+                    profiles.remove_section(install_section)
+                    # Write back the modified profiles.ini
+                    with open(profiles_file, 'w') as profiles_fd:
+                        profiles.write(profiles_fd, False)
+                    return
+
+
+if __name__ == '__main__':
+    if len(sys.argv) != 2 or not os.path.isfile(sys.argv[1]):
+        expected_arg = '/path/to/profiles_dir/profiles.ini'
+        print('Usage: {} {}'.format(sys.argv[0], expected_arg))
+        sys.exit(1)
+    _patch_imported_profiles(sys.argv[1])
diff --git a/snapcraft.yaml b/snapcraft.yaml
index 3dfffd3..5623fb7 100644
--- a/snapcraft.yaml
+++ b/snapcraft.yaml
@@ -10,7 +10,7 @@ compression: lzo
 apps:
   thunderbird:
     command-chain: [ bin/gpg-shim, bin/tmpdir ]
-    command: thunderbird-bin
+    command: thunderbird.launcher
     extensions: [ gnome-3-38 ]
     environment:
       DISABLE_WAYLAND: 1
@@ -38,6 +38,9 @@ plugs:
   etc-thunderbird-policies:
     interface: system-files
     read: [/etc/thunderbird/policies]
+  dot-thunderbird:
+    interface: personal-files
+    read: [$HOME/.thunderbird]
 
 parts:
   thunderbird:
@@ -96,3 +99,8 @@ parts:
         cd "/snap/$snap/current" && find . -type f,l -exec rm -f "$SNAPCRAFT_PRIME/{}" \;
       done
 
+  launcher:
+    plugin: nil
+    override-prime: |
+      cp "$SNAPCRAFT_PROJECT_DIR/thunderbird.launcher" "$SNAPCRAFT_PRIME/"
+      cp "$SNAPCRAFT_PROJECT_DIR/patch-default-profile.py" "$SNAPCRAFT_PRIME/"
diff --git a/thunderbird.launcher b/thunderbird.launcher
new file mode 100755
index 0000000..5782eac
--- /dev/null
+++ b/thunderbird.launcher
@@ -0,0 +1,45 @@
+#!/bin/sh
+
+REALHOME=$(getent passwd $(id -u) | cut -d ':' -f 6)
+
+# When running the snap for the first time, try and locate an existing
+# thunderbird config in $HOME/.thunderbird and import it.
+# This requires the personal-files plug to be connected.
+# This is a stopgap measure until proper profile migration is implemented
+# in thunderbird.
+SNAPDOT="$SNAP_USER_COMMON/.thunderbird"
+if [ ! -d "$SNAPDOT" ]; then
+  HOMEDOT="$REALHOME/.thunderbird"
+  if [ -r "$HOMEDOT/profiles.ini" ]; then
+    SIZE=$(du -sb "$HOMEDOT" | cut -f 1)
+    AVAILABLE_BLOCKS=$(stat -f -c %a "$SNAP_USER_COMMON")
+    BLOCK_SIZE=$(stat -f -c %s "$SNAP_USER_COMMON")
+    AVAILABLE_SIZE=$(($AVAILABLE_BLOCKS * $BLOCK_SIZE))
+    if [ "$AVAILABLE_SIZE" -gt "$SIZE" ]; then
+      printf '%s\n' "Importing existing thunderbird profiles from $HOMEDOT"
+      TS1=$(date +%s.%3N)
+      mkdir -p "$SNAPDOT"
+      cp -R "$HOMEDOT"/* "$SNAPDOT/"
+      # Search and replace absolute file paths in plain-text config files.
+      find "$SNAPDOT" \( -name "pkcs11.txt" -o -name "extensions.json" \) \
+          -exec sed -i "s#$HOMEDOT#$SNAPDOT#g" {} \;
+      # Patch the imported profiles to set the default one for use by the snap
+      # (legacy mode, no dedicated profiles).
+      $SNAP/patch-default-profile.py "$SNAPDOT/profiles.ini"
+      TS2=$(date +%s.%3N)
+      T=$(printf '%s' "$TS1 $TS2" | awk '{printf "%.3f",$2-$1}')
+      printf '%s\n' "Import done in $T s"
+    else
+      printf '%s\n' "Not importing existing firefox profiles from $HOMEDOT "
+          "because there is not enough available space in $SNAP_USER_COMMON "
+          "(required: $SIZE bytes / available: $AVAILABLE_SIZE bytes)"
+    fi
+  fi
+fi
+
+# Default to XWayland until native Wayland support is properly tested
+# (see https://bugzilla.mozilla.org/show_bug.cgi?id=1725245)
+[ -z "$MOZ_ENABLE_WAYLAND" ] && export MOZ_ENABLE_WAYLAND=0
+unset GDK_BACKEND
+
+exec "$SNAP/thunderbird-bin" "$@"

Follow ups