Skip to content

Instantly share code, notes, and snippets.

@fgggid
Last active September 13, 2024 09:39
Show Gist options
  • Save fgggid/fdfa8868c9820ae4e141d55b0733a33d to your computer and use it in GitHub Desktop.
Save fgggid/fdfa8868c9820ae4e141d55b0733a33d to your computer and use it in GitHub Desktop.
docker overlayfs cleanup for containers and images
#! /usr/bin/python
from __future__ import print_function
import glob
import json
import six
import subprocess
CMD_IMAGES = 'docker image ls -aq'
CMD_CONTAINERS = 'docker ps -aq'
# Function to run a shell command and return the output as a list of strings
def run_exec(command):
stdout = stderr = None
try:
# For Python 2.7 compatibility: Use 'universal_newlines=True' for proper decoding in subprocess
result = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
stdout, stderr = result.communicate()
if result.returncode != 0:
print("Error: ", stderr)
return result.returncode, stdout, stderr
except Exception as e:
print("Error running command {}: {}".format(command, e))
return -1, stdout, stderr
def get_docker_ids(command):
try:
# For Python 2.7 compatibility: Use 'universal_newlines=True' for proper decoding in subprocess
ret, stdout, stderr = run_exec(command)
if ret != 0:
print("Error: ", stderr)
return stdout.splitlines()
except Exception as e:
print("Error running command {}: {}".format(command, e))
return []
# Get all container IDs
check_ids = get_docker_ids(CMD_CONTAINERS)
# Get all image IDs
check_ids.extend(get_docker_ids(CMD_IMAGES))
# print("IDs to check:", check_ids)
CMD_LAYERS = 'docker inspect -f "{{json .GraphDriver.Data}}" '
DIR_BASE = '/var/lib/docker/overlay2/'
def get_layer_ids(check_id):
try:
cmd = CMD_LAYERS + check_id
# print('Run: ', cmd)
ret, stdout, stderr = run_exec(cmd)
except Exception as e:
print("Error running command {}: {}".format(cmd, e))
return []
# print('data: ', stdout)
layers = json.loads(stdout)
# print('Layer data: ', layers)
ids = {}
for key in layers:
path = layers[key]
# print('Path: ', layers[key])
path = path.replace(DIR_BASE, '')
id = path.split('/')[0]
ids[id] = ids.get(id, 0) + 1
return ids
layer_ids = {}
for n in check_ids:
layer_ids.update(get_layer_ids(n))
# print('Layer IDs: ', layer_ids)
dirs = glob.glob(DIR_BASE + '*')
dirs.sort()
for n in dirs:
basename = n.replace(DIR_BASE, '')
if basename in ['l', 'backingFsBlockDev']:
continue
if basename in layer_ids:
continue
cmd = 'rm -rf ' + n
run_exec(cmd)
mount -t overlay > /tmp/overlay.log
docker ps -aq | xargs -ri docker inspect {} | grep Upper | awk -F/ '{print $6}' | xargs -ri sed -i "/{}/d" /tmp/overlay.log
cat /tmp/overlay.log | awk '{print $3}' | awk -F/ -v OFS=/ '{printf "umount %s\n", $0; $NF=""; sub(/\/$/, ""); printf "rm -rf %s\n", $0}'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment