{"id":27359279,"url":"https://github.com/rackerlabs/kthresher","last_synced_at":"2025-04-13T00:27:52.853Z","repository":{"id":62574749,"uuid":"43979167","full_name":"rackerlabs/kthresher","owner":"rackerlabs","description":"Tool to remove unused kernels in Debian/Ubuntu","archived":false,"fork":false,"pushed_at":"2023-11-22T09:46:48.000Z","size":131,"stargazers_count":17,"open_issues_count":8,"forks_count":12,"subscribers_count":19,"default_branch":"master","last_synced_at":"2025-04-08T09:46:48.144Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rackerlabs.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-10-09T20:41:44.000Z","updated_at":"2024-11-03T00:45:10.000Z","dependencies_parsed_at":"2022-11-03T18:32:27.203Z","dependency_job_id":null,"html_url":"https://github.com/rackerlabs/kthresher","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rackerlabs%2Fkthresher","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rackerlabs%2Fkthresher/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rackerlabs%2Fkthresher/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rackerlabs%2Fkthresher/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rackerlabs","download_url":"https://codeload.github.com/rackerlabs/kthresher/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248650840,"owners_count":21139670,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-04-13T00:27:52.240Z","updated_at":"2025-04-13T00:27:52.842Z","avatar_url":"https://github.com/rackerlabs.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"|logo0|\n\nkthresher\n=========\n\n.. image:: https://img.shields.io/github/release/rackerlabs/kthresher.svg\n        :target: https://github.com/rackerlabs/kthresher/releases/latest\n        :alt: Github release\n.. image:: https://img.shields.io/travis/rackerlabs/kthresher/master.svg?logo=travis\u0026label=master\n        :target: https://travis-ci.org/rackerlabs/kthresher\n        :alt: Build Master Status\n.. image:: https://img.shields.io/travis/rackerlabs/kthresher/master.svg?logo=travis\u0026label=development\n        :target: https://travis-ci.org/rackerlabs/kthresher\n        :alt: Build Development Status\n.. image:: https://img.shields.io/github/license/rackerlabs/kthresher.svg\n        :target: https://raw.githubusercontent.com/rackerlabs/kthresher/master/LICENSE\n        :alt: License\n.. image:: https://img.shields.io/twitter/url/https/github.com/rackerlabs/kthresher.svg?style=social\n        :target: https://twitter.com/intent/tweet?text=Check%20this%20out:\u0026url=https%3A%2F%2Fgithub.com%2Frackerlabs%2Fkthresher\n        :alt: Twitter\n\nTool to remove unused kernels that were installed automatically in Debian/Ubuntu.\n\nThis tool removes those kernel packages marked as candidate for autoremoval. Those packages are generally installed via Unattended upgrade or meta-packages.\n\nBy default, on apt 1.0 and below, the booted kernel, the latest-installed kernel and the latest kernel are set to \"NeverAutoRemove\". Or, for apt 1.2 and above, the booted kernel, the latest-installed kernel, the latest kernel and the second-latest kernel are set to \"NeverAutoRemove\".\n\nThe official documentation has multiple suggestions on how to remove kernels:\n  https://help.ubuntu.com/community/RemoveOldKernels\n\nA great recommendation is to make use of unattended-upgrades `u-u` (`debian \u003chttps://wiki.debian.org/UnattendedUpgrades\u003e`__, `ubuntu \u003chttps://help.ubuntu.com/community/AutomaticSecurityUpdates\u003e`__). Since version **1.0** (`debian \u003chttps://packages.debian.org/search?keywords=unattended-upgrades\u003e`__, `ubuntu \u003chttps://packages.ubuntu.com/search?keywords=unattended-upgrades\u003e`__) *u-u* removes unused kernel packages by default (*Remove-Unused-Kernel-Packages*).\nSome distribution versions may not make reference or may comment out that setting in its configuration, but unless it is explicitly disabled, *u-u* will attempt to remove unused kernels. `More info here \u003chttps://github.com/rackerlabs/kthresher/issues/79\u003e`__.\n\nFor scenarios where *u-u* is not available or older than **1.0**, `kthresher` is still a good option.\n\n\n*thresher - A device that first separates the head of a stalk of grain from the straw, and then further separates the kernel from the rest of the head.*\n\n-----\n\n|version| |downloads-pypi| |versions| |license| |stars-github|\n\n-----\n\n.. contents:: Table of Contents\n   :depth: 1\n   :backlinks: none\n\n-----\n\nHow a package is marked for autoremoval?\n----------------------------------------\n\nWhenever a package is auto-installed and there is no other dependency for it, the package is marked as a candidate for autoremoval, there is an exception if the *APT* configuration does have the package marked as \"NeverAutoRemove\".\n\n\nHow the kernel image is added into the \"APT::NeverAutoRemove::\" config?\n-----------------------------------------------------------------------\n\nWhen a kernel image is installed the *postinstall* script will issue the *run-parts* on */etc/kernel/postinst.d/* and */etc/kernel/postinst.d/${version}* if any exist.  The *run-parts* script will run each one of the scripts located in that directory, e.g.\n\n.. code-block:: bash\n\n    # ls -1 /etc/kernel/postinst.d/\n    apt-auto-removal\n    initramfs-tools\n    update-notifier\n    x-grub-legacy-ec2\n    zz-update-grub\n\nAll the scripts found by *run-parts* are executed on post install of the kernel package and the output of apt-get install/upgrade/dist-upgrade will show them, e.g.\n\n.. code-block:: bash\n\n    run-parts: executing /etc/kernel/postinst.d/apt-auto-removal 3.13.0-96-generic /boot/vmlinuz-3.13.0-96-generic\n    run-parts: executing /etc/kernel/postinst.d/initramfs-tools 3.13.0-96-generic /boot/vmlinuz-3.13.0-96-generic\n    run-parts: executing /etc/kernel/postinst.d/update-notifier 3.13.0-96-generic /boot/vmlinuz-3.13.0-96-generic\n    run-parts: executing /etc/kernel/postinst.d/x-grub-legacy-ec2 3.13.0-96-generic /boot/vmlinuz-3.13.0-96-generic\n    run-parts: executing /etc/kernel/postinst.d/zz-update-grub 3.13.0-96-generic /boot/vmlinuz-3.13.0-96-generic\n\nThe first script *\"apt-auto-removal\"* takes care of adding a configuration in /etc/apt/apt.conf.d/01autoremove-kernels this script generates that list based on the logic described above, it means that the NeverAutoRemove may have anything between two to three kernels listed.\n\nSupported Operating Systems\n---------------------------\n\n* Debian (Tested on Version(s))\n    * `8 \u003chttps://www.debian.org/releases/jessie/\u003e`__\n    * `9 \u003chttps://www.debian.org/releases/stretch/\u003e`__\n* Ubuntu (Tested on Version(s))\n    * `12.04 \u003chttp://releases.ubuntu.com/precise/\u003e`__\n    * `14.04 \u003chttp://releases.ubuntu.com/trusty/\u003e`__\n    * `16.04 \u003chttp://releases.ubuntu.com/xenial/\u003e`__\n    * `17.10 \u003chttp://releases.ubuntu.com/artful/\u003e`__\n\n\nInstallation\n------------\nscript\n~~~~~~\n\n.. code-block:: bash\n\n    wget -O kthresher https://raw.githubusercontent.com/rackerlabs/kthresher/master/kthresher.py\n    chmod u+x kthresher\n\npip\n~~~\n\n.. code-block:: bash\n\n    pip install kthresher\n\nor\n\n.. code-block:: bash\n\n    pip install git+https://github.com/rackerlabs/kthresher.git\n\nGithub\n~~~~~~\n\n.. code-block:: bash\n\n    git clone https://github.com/rackerlabs/kthresher.git\n    cd kthresher \u0026\u0026 python setup.py install\n\n\nUsage\n-----\n\n.. code-block::\n\n    $ kthresher -h\n    usage: kthresher [-h] [-c FILE] [-d] [-H] [-k [N]] [-p] [-s] [-v] [-V]\n    \n    Purge Unused Kernels.\n    \n    optional arguments:\n      -h, --help            show this help message and exit\n      -c FILE, --config FILE\n                            Config file, default is /etc/kthresher.conf\n      -d, --dry-run         List unused kernel images available to purge(dry run).\n                            Is always verbose.\n      -H, --headers         Include the search for kernel headers.\n      -k [N], --keep [N]    Number of kernels to keep, default 1.\n      -p, --purge           Purge Unused Kernels.\n      -s, --show-autoremoval\n                            Show kernel packages available for autoremoval.\n      -v, --verbose         Be verbose.\n      -V, --version         Print version.\n\n\nExamples\n--------\n\nList which kernel images and its dependencies would remove(dry run)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n.. code-block::\n\n    # kthresher -d\n    INFO: Attempting to read /etc/kthresher.conf.\n    INFO: Config file /etc/kthresher.conf is empty or does not exist, ignoring.\n    INFO: Options: {'purge': False, 'verbose': False, 'dry_run': True, 'keep': 1}\n    INFO: ----- DRY RUN -----\n    INFO: Running kernel is linux-image-3.13.0-83-generic v[3.13.0-83.127]\n    INFO: Attempting to keep 1 kernel package(s)\n    INFO: Found 4 kernel image(s) installed and available for autoremoval\n    INFO: Pre-sorting: ['3.16.0-60.80~14.04.1', '3.13.0-77.121', '3.13.0-63.103', '3.16.0-33.44~14.04.1']\n    INFO: Post-sorting: ['3.13.0-63.103', '3.13.0-77.121', '3.16.0-33.44~14.04.1', '3.16.0-60.80~14.04.1']\n    INFO:   Purging packages from version: 3.13.0-63.103\n    INFO:           Purging: linux-image-extra-3.13.0-63-generic\n    INFO:           Purging: linux-image-3.13.0-63-generic\n    INFO:   Purging packages from version: 3.13.0-77.121\n    INFO:           Purging: linux-image-3.13.0-77-generic\n    INFO:           Purging: linux-image-extra-3.13.0-77-generic\n    INFO:   Purging packages from version: 3.16.0-33.44~14.04.1\n    INFO:           Purging: linux-image-3.16.0-33-generic\n\n\nShow all kernel packages available for autoremoval\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n.. code-block::\n\n    # kthresher -s\n    List of kernel packages available for autoremoval:\n                   Version Package\n              3.13.0.83.89 linux-generic\n              3.13.0-51.84 linux-headers-3.13.0-51\n              3.13.0-51.84 linux-headers-3.13.0-51-generic\n             3.13.0-71.114 linux-headers-3.13.0-71\n             3.13.0-71.114 linux-headers-3.13.0-71-generic\n             3.13.0-77.121 linux-headers-3.13.0-77\n             3.13.0-77.121 linux-headers-3.13.0-77-generic\n             3.13.0-79.123 linux-headers-3.13.0-79\n             3.13.0-79.123 linux-headers-3.13.0-79-generic\n             3.13.0-63.103 linux-image-3.13.0-63-generic\n             3.13.0-77.121 linux-image-3.13.0-77-generic\n      3.16.0-33.44~14.04.1 linux-image-3.16.0-33-generic\n      3.16.0-60.80~14.04.1 linux-image-3.16.0-60-generic\n             3.13.0-63.103 linux-image-extra-3.13.0-63-generic\n             3.13.0-77.121 linux-image-extra-3.13.0-77-generic\n              3.13.0.83.89 linux-image-generic\n\n\nPurge Unused Kernels, keep 3 kernels and be verbose\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n.. code-block::\n\n    # kthresher -p -k3 -v\n    INFO: Attempting to read /etc/kthresher.conf.\n    INFO: Config file /etc/kthresher.conf is empty or does not exist, ignoring.\n    INFO: Options: {'purge': True, 'verbose': True, 'dry_run': False, 'keep': 3}\n    INFO: Running kernel is linux-image-3.13.0-83-generic v[3.13.0-83.127]\n    INFO: Attempting to keep 3 kernel package(s)\n    INFO: Found 4 kernel image(s) installed and available for autoremoval\n    INFO: Pre-sorting: ['3.16.0-60.80~14.04.1', '3.13.0-77.121', '3.13.0-63.103', '3.16.0-33.44~14.04.1']\n    INFO: Post-sorting: ['3.13.0-63.103', '3.13.0-77.121', '3.16.0-33.44~14.04.1', '3.16.0-60.80~14.04.1']\n    INFO:   Purging packages from version: 3.13.0-63.103\n    INFO:           Purging: linux-image-extra-3.13.0-63-generic\n    INFO:           Purging: linux-image-3.13.0-63-generic\n    Fetched 0 B in 0s (0 B/s)\n    (Reading database ... 169514 files and directories currently installed.)\n    Removing linux-image-extra-3.13.0-63-generic (3.13.0-63.103) ...\n    run-parts: executing /etc/kernel/postinst.d/apt-auto-removal 3.13.0-63-generic /boot/vmlinuz-3.13.0-63-generic\n    run-parts: executing /etc/kernel/postinst.d/initramfs-tools 3.13.0-63-generic /boot/vmlinuz-3.13.0-63-generic\n    update-initramfs: Generating /boot/initrd.img-3.13.0-63-generic\n    run-parts: executing /etc/kernel/postinst.d/zz-update-grub 3.13.0-63-generic /boot/vmlinuz-3.13.0-63-generic\n    Generating grub configuration file ...\n    Found linux image: /boot/vmlinuz-3.16.0-60-generic\n    Found initrd image: /boot/initrd.img-3.16.0-60-generic\n    Found linux image: /boot/vmlinuz-3.16.0-33-generic\n    Found initrd image: /boot/initrd.img-3.16.0-33-generic\n    Found linux image: /boot/vmlinuz-3.13.0-83-generic\n    Found initrd image: /boot/initrd.img-3.13.0-83-generic\n    Found linux image: /boot/vmlinuz-3.13.0-77-generic\n    Found initrd image: /boot/initrd.img-3.13.0-77-generic\n    Found linux image: /boot/vmlinuz-3.13.0-63-generic\n    Found initrd image: /boot/initrd.img-3.13.0-63-generic\n    done\n    Purging configuration files for linux-image-extra-3.13.0-63-generic (3.13.0-63.103) ...\n    Removing linux-image-3.13.0-63-generic (3.13.0-63.103) ...\n    Examining /etc/kernel/postrm.d .\n    run-parts: executing /etc/kernel/postrm.d/initramfs-tools 3.13.0-63-generic /boot/vmlinuz-3.13.0-63-generic\n    update-initramfs: Deleting /boot/initrd.img-3.13.0-63-generic\n    run-parts: executing /etc/kernel/postrm.d/zz-update-grub 3.13.0-63-generic /boot/vmlinuz-3.13.0-63-generic\n    Generating grub configuration file ...\n    Found linux image: /boot/vmlinuz-3.16.0-60-generic\n    Found initrd image: /boot/initrd.img-3.16.0-60-generic\n    Found linux image: /boot/vmlinuz-3.16.0-33-generic\n    Found initrd image: /boot/initrd.img-3.16.0-33-generic\n    Found linux image: /boot/vmlinuz-3.13.0-83-generic\n    Found initrd image: /boot/initrd.img-3.13.0-83-generic\n    Found linux image: /boot/vmlinuz-3.13.0-77-generic\n    Found initrd image: /boot/initrd.img-3.13.0-77-generic\n    done\n    Purging configuration files for linux-image-3.13.0-63-generic (3.13.0-63.103) ...\n    Examining /etc/kernel/postrm.d .\n    run-parts: executing /etc/kernel/postrm.d/initramfs-tools 3.13.0-63-generic /boot/vmlinuz-3.13.0-63-generic\n    run-parts: executing /etc/kernel/postrm.d/zz-update-grub 3.13.0-63-generic /boot/vmlinuz-3.13.0-63-generic\n\n\nVerbose run using a non-default config file\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. code-block::\n\n    # kthresher -c myconf.conf\n    INFO: Attempting to read myconf.conf.\n    INFO: Options found: ['keep', 'dry_run'].\n    INFO: Valid setting found \"keep\"\n    INFO:   keep = 1\n    INFO: Valid setting found \"dry_run\"\n    INFO:   dry_run = True\n    INFO: Options: {'purge': False, 'verbose': True, 'dry_run': True, 'keep': 1}\n    INFO: ----- DRY RUN -----\n    INFO: Running kernel is linux-image-3.13.0-83-generic v[3.13.0-83.127]\n    INFO: Attempting to keep 1 kernel package(s)\n    INFO: Found 2 kernel image(s) installed and available for autoremoval\n    INFO: Pre-sorting: ['3.16.0-60.80~14.04.1', '3.16.0-33.44~14.04.1']\n    INFO: Post-sorting: ['3.16.0-33.44~14.04.1', '3.16.0-60.80~14.04.1']\n    INFO:   Purging packages from version: 3.16.0-33.44~14.04.1\n    INFO:           Purging: linux-image-3.16.0-33-generic\n\nContent of myconf.conf is:\n.. code-block::\n\n    [main]\n    keep    = 1\n    dry_run = yes\n    #purge = yes\n\n\nDry run including headers\n~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. code-block::\n\n    # kthresher -v -d -H\n    INFO: Attempting to read /etc/kthresher.conf.\n    INFO: Options found: ['keep', 'dry_run', 'purge', 'verbose'].\n    INFO: Valid setting found \"keep\"\n    INFO:   keep = 2\n    INFO: Valid setting found \"dry_run\"\n    INFO:   dry_run = False\n    INFO: Valid setting found \"purge\"\n    INFO:   purge = True\n    INFO: Valid setting found \"verbose\"\n    INFO:   verbose = True\n    INFO: Options: {'verbose': True, 'dry_run': True, 'keep': 2, 'purge': True, 'headers': True}\n    INFO: ----- DRY RUN -----\n    INFO: Running kernel is linux-image-3.13.0-83-generic v[3.13.0-83.127]\n    INFO: Attempting to keep 2 kernel package(s)\n    INFO: Found 4 kernel image(s) installed and available for autoremoval\n    INFO: Pre-sorting: ['3.16.0-60.80~14.04.1', '3.16.0-33.44~14.04.1', '3.13.0-85.129', '3.13.0-79.123']\n    INFO: Post-sorting: ['3.13.0-79.123', '3.13.0-85.129', '3.16.0-33.44~14.04.1', '3.16.0-60.80~14.04.1']\n    INFO:   Purging packages from version: 3.13.0-79.123\n    INFO:           Purging: linux-image-3.13.0-79-generic\n    INFO:           Purging: linux-headers-3.13.0-79-generic\n    INFO:           Purging: linux-headers-3.13.0-79\n    INFO:   Purging packages from version: 3.13.0-85.129\n    INFO:           Purging: linux-image-3.13.0-85-generic\n    INFO:           Purging: linux-headers-3.13.0-85\n    INFO:           Purging: linux-headers-3.13.0-85-generic\n\n\nTesting\n-------\n\nThe below code can be used to install up to a fixed amount of kernels and headers if available of the form \"linux-(image|headers)-[0-9].*-(generic|amd64)\" at the end it should end up with two or three kernels in the NeverAutoRemove list, including the latest, the prior to latest and the running kernel.\n\n.. code-block:: python\n\n    #!/usr/bin/env python\n    '''Installs available linux-image-* and linux-headers-*\n    And set them for autoremoval, so kthresher can be used for testing.\n    '''\n    \n    import re\n    import apt\n    import sys\n    from platform import uname\n    \n    def autorm_install(pkgs):\n        '''Install a list of packages and set them autoremovable.\n        '''\n        latest_kernel = ''\n        ac = apt.Cache()\n        for pkg in pkgs:\n            latest_kernel = pkg\n            k = ac[pkg]\n            if not k.is_installed:\n                k.mark_install(from_user=False)\n        try:\n            ac.commit(install_progress=None)\n        except apt.cache.LockFailedException as lfe:\n            print('{}, are you root?'.format(lfe))\n            sys.exit(1)\n        except SystemError:\n            print('Something failed')\n            sys.exit(1)\n    \n    def get_pkg(regex):\n        '''Get a list of packages available that match the regex.\n        '''\n        pkgs = []\n        ac = apt.Cache()\n        ac.update()\n        for pkg in ac:\n            if re.match(regex, pkg.name):\n                # ignore running kernel\n                if pkg.name == 'linux-image-{0}'.format(uname()[2]):\n                    continue\n                pkgs.append(pkg.name)\n        return pkgs\n    \n    def main():\n        limit = 5\n        if len(sys.argv) \u003e 1:\n            try:\n                limit = int(sys.argv[1])\n            except:\n                print(\"Use an integer as the limit of pkgs to install.\")\n                sys.exit(1)\n        print(\"Installing {} kernels/headers if available...\".format(limit))\n        kernel_regex = \"^linux-image-\\d\\..*-(generic|amd64)$\"\n        header_regex = \"^linux-headers-\\d\\..*-(generic|amd64)$\"\n        kernels = get_pkg(kernel_regex)\n        headers = get_pkg(header_regex)\n        pkgs = kernels[0:limit] + headers[0:limit]\n        print(\"Installing {} packages total\\n\\tkernels: {}\\n\\theaders: {}\"\n              .format(len(pkgs), kernels[0:limit], headers[0:limit]))\n        autorm_install(pkgs)\n\n    if __name__ == \"__main__\":\n        main()\n\n\n\nBugs\n----\n\nSubmit Bug reports, feature requests via `issues \u003chttps://github.com/rackerlabs/kthresher/issues\u003e`__.\n\nLogos\n-----\n\nThe art was created by `Carlos Garcia \u003chttps://hellyeahdesign.com.mx\u003e`__ \u003chellyeahdesign AT gmail DOT com\u003e and released under CC BY-SA 4.0\n\n+---------+---------+\n| |logo0| | |logo1| |\n+---------+---------+\n| |logo2| | |logo3| |\n+---------+---------+\n\n.. image:: https://i.creativecommons.org/l/by-sa/4.0/88x31.png\n   :target: http://creativecommons.org/licenses/by-sa/4.0/\n   :alt: Creative Commons License\n\n-----\n\n.. |version| image:: https://img.shields.io/pypi/v/kthresher.svg\n        :target: https://github.com/rackerlabs/kthresher/releases/latest\n        :alt: Latest Version\n.. |downloads-pypi| image:: https://img.shields.io/pypi/dm/kthresher.svg\n        :target: https://pypi.python.org/pypi/kthresher\n        :alt: PyPi Downloads\n.. |stars-github| image::\thttps://img.shields.io/github/stars/rackerlabs/kthresher.svg\n        :target: https://github.com/rackerlabs/kthresher\n        :alt: Github Stars\n.. |versions| image:: https://img.shields.io/pypi/pyversions/kthresher.svg\n        :target: https://github.com/rackerlabs/kthresher/releases\n        :alt: Versions\n.. |license| image:: https://img.shields.io/pypi/l/kthresher.svg\n        :target: https://github.com/rackerlabs/kthresher/blob/master/LICENSE\n        :alt: License\n\n.. |logo0| image:: https://github.com/rackerlabs/kthresher/wiki/img/kthresher.png      \n\n.. |logo1| image:: https://github.com/rackerlabs/kthresher/wiki/img/kthresher_horiz.png\n\n.. |logo2| image:: https://github.com/rackerlabs/kthresher/wiki/img/kthresher_circ.png\n\n.. |logo3| image:: https://github.com/rackerlabs/kthresher/wiki/img/kthresher_half.png\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frackerlabs%2Fkthresher","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frackerlabs%2Fkthresher","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frackerlabs%2Fkthresher/lists"}