18

While examining the snap packages that are installed in a system, I noticed that some packages have a duplicate, one having an over revision number while the other having a newer revision number. For such duplicated packages, my questions are:

  1. Why are they duplicated?
  2. Can I remove the older package to ensure better disk space management?
  3. How do I remove the older package?

Below are examples of packages that do and do not have duplicates:

$ du -hcs /var/lib/snapd/snaps/*
31M /var/lib/snapd/snaps/2048x_3.snap
286M    /var/lib/snapd/snaps/atom_282.snap
4.0K    /var/lib/snapd/snaps/bare_5.snap
72M /var/lib/snapd/snaps/bitwarden_58.snap
72M /var/lib/snapd/snaps/bitwarden_59.snap
196M    /var/lib/snapd/snaps/blender_1113.snap
214M    /var/lib/snapd/snaps/blender_1237.snap
9.1M    /var/lib/snapd/snaps/canonical-livepatch_119.snap
9.1M    /var/lib/snapd/snaps/canonical-livepatch_126.snap
148M    /var/lib/snapd/snaps/chromium_1854.snap
148M    /var/lib/snapd/snaps/chromium_1864.snap
17M /var/lib/snapd/snaps/chromium-ffmpeg_23.snap
18M /var/lib/snapd/snaps/chromium-ffmpeg_24.snap
....

~$ ls -lh /var/lib/snapd/snaps/ total 12G -rw------- 2 root root 31M Aug 5 06:23 2048x_3.snap -rw------- 2 root root 286M Aug 5 08:35 atom_282.snap -rw------- 2 root root 4.0K Sep 22 18:17 bare_5.snap -rw------- 1 root root 72M Oct 30 00:20 bitwarden_58.snap -rw------- 1 root root 72M Dec 9 04:28 bitwarden_59.snap -rw------- 1 root root 196M Nov 18 04:06 blender_1113.snap -rw------- 1 root root 214M Dec 4 09:39 blender_1237.snap -rw------- 2 root root 9.1M Nov 17 21:06 canonical-livepatch_119.snap -rw------- 2 root root 9.1M Nov 22 22:39 canonical-livepatch_126.snap -rw------- 1 root root 148M Dec 16 04:28 chromium_1854.snap -rw------- 1 root root 148M Jan 8 08:33 chromium_1864.snap -rw------- 1 root root 17M Sep 3 06:29 chromium-ffmpeg_23.snap -rw------- 2 root root 18M Nov 29 14:23 chromium-ffmpeg_24.snap ....

On the system that I am looking at, the total disk space utilized by /var/lib/snapd/snaps/* is 12,180.248 MB. The disk space of all the duplicated packages(i.e. older revision of the same package) is 4,163.1 MB. In short, the older revision packages currently takes up 34.18% of the 12,180.248 MB. This appears to be a cost to using SNAP apps that I had not realised before.

Sun Bear
  • 2,302
  • Assuming you don't mind taking a risk... why not make a backup of the /var/.../snaps/ folder somewhere safe, removing the old versions, rebooting, and seeing if it works? You can always restore your backup, and then you can answer your own question. – cocomac Jan 11 '22 at 04:30
  • 2
    BTW if you're running low on space then consider installing the apt versions of these softwares. They are lighter and better in everything. – Error404 Jan 11 '22 at 04:35
  • 1
    @cocomac I am hoping that I don't have to experiment to learn the answer to my questions as SNAP packages have been in practice for quite some time. There should be some SOP or standard knowledge by now on this matter. – Sun Bear Jan 11 '22 at 04:38
  • Snaps are changing again (eg. https://ubuntu.com//blog/the-future-of-snapcraft) which could be what @Someone was thinking/talking about... rules that apply to a single snap, may not apply to others created under a different environment (core16, core18, core20, and soon core22) so it's not a single set of rules; though of course many rules apply to all. – guiverc Jan 11 '22 at 04:52
  • @Someone snap refresh did not remove the duplicated packages. – Sun Bear Jan 11 '22 at 04:56
  • @Someone I found that Snap packages are typically more up to date than apt packages. However, they can be at times more troublesome to use. Some features need extra commands to enable. But I hear you that they are lighter to use. Thanks for your many helpful inputs. :) – Sun Bear Jan 11 '22 at 05:36
  • @Someone I have incorporated my learning from the inputs by you, matigo and user535733 to create this remove_disabled_snap_pkgs.py python script to do the job. – Sun Bear Jan 12 '22 at 04:12
  • @SunBear Good Job! I like using scripts for everything. I've git cloned your repository but haven't tested it yet. Hopefully, it will work :D – Error404 Jan 12 '22 at 04:24
  • @Someone Thanks. Do let me know if improvements/corrections are needed. It worked at my end. :) – Sun Bear Jan 12 '22 at 04:48
  • @Someone I have added more comments to the script. – Sun Bear Jan 12 '22 at 11:24

4 Answers4

24

To answer your questions:

Why are they duplicated?

⇢ They're different revisions (versions), not duplications.

Can I remove the older package to ensure better disk space management?

⇢ Yes. It's your computer, after all.

How do I remove the older package?

You can do this in Terminal like this:

snap remove {snap} --revision={revision}

You can also tell the system how many past versions to limit itself to like this:

sudo snap set system refresh.retain=2

Note: The value must be between 2 and 20, and a number like 2 or 3 is generally recommended to save storage space and allow a rollback in the event of a bad update.

If you would like to list all the snaps and their versions, you can run this command:

snap list --all

Which will give you something like:

Name                 Version                     Rev    Tracking         Publisher   Notes
bare                 1.0                         5      latest/stable    canonical✓  base
canonical-livepatch  10.0.1                      119    latest/stable    canonical✓  disabled
canonical-livepatch  10.1.2                      126    latest/stable    canonical✓  -
core                 16-2.52                     11798  latest/stable    canonical✓  core,disabled
core                 16-2.52.1                   11993  latest/stable    canonical✓  core
core18               20211028                    2253   latest/stable    canonical✓  base
core18               20211015                    2246   latest/stable    canonical✓  base,disabled
core20               20211115                    1242   latest/stable    canonical✓  base,disabled
core20               20211129                    1270   latest/stable    canonical✓  base
gnome-3-28-1804      3.28.0-19-g98f9e67.98f9e67  145    latest/stable    canonical✓  disabled
gnome-3-28-1804      3.28.0-19-g98f9e67.98f9e67  161    latest/stable    canonical✓  -
gnome-3-34-1804      0+git.3556cb3               77     latest/stable/…  canonical✓  -
gnome-3-34-1804      0+git.3556cb3               72     latest/stable/…  canonical✓  disabled
gnome-3-38-2004      0+git.cd626d1               87     latest/stable    canonical✓  -
gnome-3-38-2004      0+git.6ba6040               76     latest/stable    canonical✓  disabled
gtk-common-themes    0.1-52-gb92ac40             1515   latest/stable/…  canonical✓  disabled
gtk-common-themes    0.1-59-g7bca6ae             1519   latest/stable/…  canonical✓  -
snap-store           3.38.0-66-gbd5b8f7          558    latest/stable/…  canonical✓  -
snap-store           3.38.0-64-g23c4c77          547    latest/stable/…  canonical✓  disabled
snapd                2.53.2                      14066  latest/stable    canonical✓  snapd,disabled
snapd                2.53.4                      14295  latest/stable    canonical✓  snapd

Need a Script?

IMPORTANT: You will want to check the output of snap list --all on your computer before continuing, and the following is a script that should not be copy/pasted without sanity checking if you are using a locale that is not en_US.UTF-8.

The Script:

#!/bin/bash
# This script will remove disabled snap revisions.
set -eu

LANG=C snap list --all | awk '/disabled/{print $1, $3}' | while read name rev; do snap remove "$name" --revision="$rev" done

This will run snap list -all and extract the lines that contain the word disabled. This will be different depending on your locale, so check the output of the function first, then update awk '/disabled/ to replace disabled with the label that is found in your output.

Save the script to a file (for example scrub-snaps.sh) and then set it as being executable:

sudo chmod +x scrub-snaps.sh

Now you can run it, remembering to use sudo:

sudo ./scrub-snaps.sh

Note: sudo was not part of the script, but can be added if you prefer to have it in there. Either way, you'll be prompted for a password if required.

Error404
  • 7,440
matigo
  • 22,138
  • 7
  • 45
  • 75
8

Keeping at least one older version of a snap is inherent in the design.

Snap packages were originally designed for a variety of environments where there is often no human admin and/or no way to attach a keyboard and monitor...like phones or IOT devices. Resiliency is a critical requirement for these systems: If an application crashes or an upgrade is corrupted, some form of guaranteed rollback without human intervention is needed. Hence the requirement for at least one older version on-hand.

Folks on classic desktops and servers don't care much about that rollback capability. They like different snap design elements: The secure automatic upgrades that are independent of the OS, the read-only squashfs tamper-prevention, the process confinement, etc.

But it's all a single standard, so you get the rollback capability, too. Even if you think you won't use it.

You cannot "disable" the rollback capability of snaps -- it's not really a "feature" but a key design element.

user535733
  • 62,253
  • Thanks for explaining. In the system that I looked at, I discovered that the cost of the minimum redundancy feature of Snap is at least 34% of the total disk space of all the Snap packages. – Sun Bear Jan 11 '22 at 05:30
  • 1
    Despite the design intent for redundancy, did the Snap development team also provide a command to remove all older revisions of all snap packages? This capability is to better serve the folks on classic desktops and servers who don't care much about that rollback capability. – Sun Bear Jan 11 '22 at 05:47
  • Sure, the answer by @matigo explains how. This answer complements by explaining why. – user535733 Jan 11 '22 at 14:46
2

Building on @matigo answer, I wrote a python script to automate the removal of disabled SNAP packages. It allows a user to visually check the snap packages before proceeding with (or not) the removal process. An example of what the executed script does is shown in the link.

remove_disabled_snap_pkgs.py

#!/bin/python3
''' This python script automates the removal of all disabled SNAP packages in
a system. Doing so helps free up the system's disk space. This outcome can be
significant in the situation where many disabled SNAP packages are retained in
the system.
'''
from subprocess import run, PIPE, CalledProcessError
from pathlib import Path
import sys

Assumptions

SNAP_PKGS_PATH = Path('/var/lib/snapd/snaps/')

Also, at a minimum, this directory has at least one xxx.snap file there.

def snap_list(): '''Function to execute a bash 'snap list' cmd and returns a Python dictionary of info of the ACTIVE SNAPCRAFT pkgs in the system.

pkgs_dict = {Name : {'Version':'xxx', 'Rev':'xxx', 'Tracking':'xxx',
                     'Publisher':'xxx', 'Notes':'xxx'}
            }
'''
try:
    cmd = ['snap', 'list']
    completed = run(cmd, check=True, stdout=PIPE)
except CalledProcessError as err:
    print('ERROR:', err)
else:
    headers = completed.stdout.decode('utf-8').splitlines()[0].split()
    pkgs=[line.split() for line in
          completed.stdout.decode('utf-8').splitlines()[1:]]
    pkgs_dict = {}
    for pkg in pkgs:
        pkgs_dict[pkg[0]] = {i:pkg[n+1] for n, i in enumerate(headers[1:])}
    return pkgs_dict


1. Get all SNAPCRAFT pkgs in system

all_path = sorted(SNAP_PKGS_PATH.glob('*.snap')) all_size = sum([p.stat().st_size for p in all_path])

2. Get active SNAPCRAFT pkgs in system

active_snap_pkgs = snap_list() active_path = [SNAP_PKGS_PATH / Path(k+'_'+v['Rev']+'.snap') for k, v in active_snap_pkgs.items()] active_size = sum([p.stat().st_size for p in active_path])

3. Display info and instructions in terminal

print(f'ALL (ACTIVE & DISABLED) SNAP PACKAGES IN SYSTEM:') for n, i in enumerate(all_path): size = i.stat().st_size if i in active_path: print(f'Active\t{size:>12}\t{i}') else: print(f' \t{size:>12}\t{i}')

4. Show stats on total size of All, Active & Disabled SNAPCRAFT packages

width = 12 disabled_size = all_size - active_size print('\nSIZE OF SNAP PACKAGES:') print(f'1. All : {all_size:>{width}} bytes') print(f'2. Active : {active_size:>{width}} bytes') print(f'2. Disabled : {disabled_size:>{width}} bytes or ' f'{(disabled_size/all_size):.2%} of All')

5. Make decision to remove or not to remove Disabled SNAPCRAFT packages

if disabled_size > 0: print(f'\nREMOVE ALL DISABLED SNAP PACKAGES? [y/n]') while True: decision = input() if decision in ['y', 'Y', 'yes', 'Yes', 'YES']: print('Removal in progress... pls wait') for p in all_path: if p not in active_path: stem = p.stem bar_index = stem.index('_') name = stem[:bar_index] revision = stem[bar_index+1:] cmd = ['sudo', 'snap', 'remove', name, '--revision='+revision] print(f"\n{' '.join(cmd)}") run(cmd, stdout=sys.stdout, stderr=sys.stderr, encoding='utf8') print(f'\nREMOVE ALL DISABLED SNAP PACKAGES? COMPLETED.') break elif decision in ['n', 'N', 'no', 'No', 'NO']: print(f'\nNO REMOVAL IS PERFORMED.') break else: print('Please enter only "y" or "n":') else: print(f'\nNO REMOVAL IS NEEDED.')

Sun Bear
  • 2,302
0

(writing these for extra context in case the scripts don't work)

For me, running the above scripts didn't change a lot regarding the snapds size.

So I checked what files I have: sudo ls -l /var/lib/snapd/snaps

and moved older unused snaps to a back up directory, f.e: sudo mv /var/lib/snapd/snaps/brave_2*.snap ~/Programming

Then I restarted my machine to see if everything is fine, and then deleted the backuped files.

I was able to get back approx. 4GB by doing so.

giou-k
  • 1