doker cues

Rangaswamy P V
6 min readAug 23, 2024

--

In this article we are going to see an easy diagnostic tool to inspect the Containers in your box.

The program written in Python uses argparse() to get user inputs and display the relevant outputs. Its a work in progress as more functionality is added over time.

The current supported features are image count, container count, docker stats, dangling images, container info, sha layers for a particular image in the box…

to install Docker refer to this script (dock.sh) and it automatically installs for most of the linux distributions https://github.com/rangapv/doker.git

rangapv@Rangaswamys-MacBook-Pro pydok % ./dokarg.py -h
usage: dokarg.py [-h] [-img [IMG]] [-ctan [CTAN]] [-sha SHA] [-dstat DSTAT] [-il IL] [-cl CL]

A python code to display argparse capability

options:
-h, --help show this help message and exit
-img [IMG] to display the total images in the box
-ctan [CTAN] to display the total containers in the box
-sha SHA to display the sha layers for an image-id in the box
-dstat DSTAT to display the list Docker daemon running
-il IL to display the list of images and if they are DANGLING
-cl CL to display the list of containers in this box

Hope you like this program

As it is evident from above lets play the option one by one..

rangapv@Rangaswamys-MacBook-Pro pydok % ./dokarg.py -img
**********************
total images are 2

rangapv@Rangaswamys-MacBook-Pro pydok % ./dokarg.py -ctan
**********************
total containers are 1
***********************

To display the docker statistics…

rangapv@Rangaswamys-MacBook-Pro pydok % ./dokarg.py -dstat g
the output is successful :CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
ff433abdcef9 gitlab-web-1 100.51% 1.445GiB / 1.942GiB 74.43% 1.37kB / 0B 172MB / 45.4MB 181

the Docker version installed is "Docker version 20.10.12, build e91ed57
" and install directory is "/usr/local/bin/docker"

To display the current containers…

rangapv@Rangaswamys-MacBook-Pro pydok % ./dokarg.py -cl g
***********************
The list of Containers running in the box and its repo-tag..
{'ff433abdcef9': 'gitlab/gitlab-ee:latest'}

To display the images and its usage ….

rangapv@Rangaswamys-MacBook-Pro pydok % ./dokarg.py -il g
**********************
Images in the box
Image: "kube-build:build-82b91624d4-5-v1.24.0-go1.18-bullseye.0" with ID "b0ed86d72a9d" is NOT used by any container at the moment
Image: "gitlab/gitlab-ee:latest" with ID "02e46c0524df" is used by the container "ff433abdcef9"

Note the above function displays all the un-used Images that are currently taking up space in you box.

To display the sha layers for a particlar image in the box..

rangapv@Rangaswamys-MacBook-Pro pydok % ./dokarg.py -sha 02e46c0524df
*************************
The sha layers for image id "02e46c0524df" is:
['sha256:36ffdceb4c77bf34325fb695e64ea447f688797f2f1e3af224c29593310578d2',
'sha256:25288ac9e5242839f106987ebc90e4aea9bb48b7e36f063c536aa33861bd64ac',
'sha256:76e1be690904f65d1b13d2552a4945ab52c518c118b721f5b963d785c1bd1306',
'sha256:33788bbe64a1b400e2221672a53f167d3f58eaefce4b8a5a28ad10cfed025ce6',
'sha256:1a9e24c20656cad250b42cf4e3a28d28ba5468e5d755a19bff0deac6e3bbe89d',
'sha256:d06677251256a79a8b50476ced596470038034cbb627127340a415572218b640',
'sha256:eba4f5e37d9e3f2c0bf36a383b1c4cd208aed1ba385c767a8fcc51128c577591',
'sha256:e120199f1f7c0734c76820579d30f4c6c44cbe58064b9e94fb76d0fb4299557e']
The image with id "02e46c0524df" has "8" layers

The code in itself is here…

#!/usr/bin/env python3
#author:rangapv@yahoo.com

import os
import subprocess
import sys

import io
import re
import argparse
import shutil

from subprocess import PIPE


def count1(self):
t1 = subprocess.run("docker image ls", capture_output=True, shell=True, text=True, check=True)
contlen = t1.stdout
#print(contlen)
len1 = len(contlen.splitlines())
print("**********************")
print(f'total images are {len1-1}')
# t1 = subprocess.run("docker xxximage ls", capture_output=True, shell=True, text=True, check=True)

def count2(self):
t1 = subprocess.run("docker container ps", capture_output=True, shell=True, text=True, check=True)
contlen = t1.stdout
#print(contlen)
len1 = len(contlen.splitlines())
print("**********************")
print(f'total containers are {len1-1}')
print("***********************")

def Imageid(self):
t1 = subprocess.run("docker image ls", capture_output=True, shell=True, text=True, check=True)
l = []
for line in t1.stdout.splitlines():
r = re.findall(r'\S+',line)
l.append(r[2])
return(l)


def Findsha(sha):
scount = 0
b = sha
id = Imageid(b)
#for ip in id:
ip = id
if ( b in ip ):
print("*************************")
pc = "docker inspect --format='{{{{.RootFS.Layers}}}}' {}".format(b)
pl = subprocess.run(pc, capture_output=True, shell=True, text=True, check=False)
l21 = pl.stdout
#print("l21 is {}".format(l21))
l24 = l21.replace("[","")
#print("l24 is {}".format(l24))
l25 = l24.replace("]","")
#l26 = l25.replace(" ","\n")
#print("l26 is {}".format(l26))
s = re.findall(r'\S+', l25)
print("The sha layers for image id \"{}\" is: {}".format(b,s))
print("The image with id \"{}\" has \"{}\" layers".format(b,len(s)))
#for g in s:
# g1 = sh.find(g)
#if (g1 != -1):
# print("The sha id: {} is having Guardian: {}".format(sh,ip))
#scount = scount + 1
else:
print("The image with id {} is not present to print it's sha256 value".format(b))
#print("Total Count:" + str(scount))

class docklist(argparse.Action):
def __init__(self, option_strings, dest, nargs=None, **kwargs):
if nargs is not None:
raise ValueError("nargs not allowed")
super(docklist, self).__init__(option_strings, dest, **kwargs)

def __call__(self, parser, namespace, values, option_string=None):
t1 = subprocess.run("docker stats --no-stream", capture_output=True, shell=True, text=True, check=True)
t2 = subprocess.run("docker -v", capture_output=True, shell=True, text=True, check=True)
t3 = subprocess.run("which docker", capture_output=True, shell=True, text=True, check=True)
#print("returncode is" + str(t1.returncode))
if ( t1.returncode == 0 ):
print ("the output is successful :" + t1.stdout )
print (f'the Docker version installed is \"{t2.stdout}\" and install directory is \"{t3.stdout}\"')
else:
print ("the command failed :" + str(t1))
values=t1
setattr(namespace, self.dest, values)

class Imagelist(argparse.Action):
def __init__(self, option_strings, dest, nargs=None, **kwargs):
if nargs is not None:
raise ValueError("nargs not allowed")
super(Imagelist, self).__init__(option_strings, dest, **kwargs)

def __call__(self, parser, namespace, values, option_string=None):

c1 = subprocess.run("docker container ps", capture_output=True, shell=True, text=True, check=True)
cl = {}
for line in c1.stdout.splitlines():
r = re.findall(r'\S+',line)
if (r[0] != "CONTAINER"):
c2 = subprocess.run("docker inspect --format='{{{{.Config.Image}}}}' {}".format(r[0]), capture_output=True, shell=True, text=True, check=True)
#print(t2)
if ((c2.stdout) == "\n"):
c2.stdout = "Error"
inc = inc+1
c3 = c2.stdout
cl[c3.rstrip()] = (r[0])
#cl[(r[0])] = c3.rstrip()
#print(cl)

t1 = subprocess.run("docker image ls", capture_output=True, shell=True, text=True, check=True)
l = {}
inc = 0
print("**********************")
print("Images in the box")
for line in t1.stdout.splitlines():
r = re.findall(r'\S+',line)
if (r[2] != "IMAGE"):
t2 = subprocess.run("docker inspect --format='{{{{.RepoTags}}}}' {}".format(r[2]), capture_output=True, shell=True, text=True, check=True)
#print(t2)
if ((t2.stdout) == "\n"):
t2.stdout = "NO-CONTAINER use this Image"
inc = inc+1
t3 = t2.stdout
l[t3.rstrip()] = (r[2])
#l[(r[2])] = t3.rstrip()
#print("li " , l)
temp = t3.rstrip()
temp1 = str(temp)[1:-1]
#print ("temp is " + temp1)
if temp1 in cl:
print(f'Image: \"{temp1}\" with ID \"{r[2]}\" is used by the container \"{cl[temp1]}\" ')
else:
print(f'Image: \"{temp1}\" with ID \"{r[2]}\" is NOT used by any container at the moment')

values=l,inc
# print(l)
setattr(namespace, self.dest, values)

class Containerlist(argparse.Action):
def __init__(self, option_strings, dest, nargs=None, **kwargs):
if nargs is not None:
raise ValueError("nargs not allowed")
super(Containerlist, self).__init__(option_strings, dest, **kwargs)

def __call__(self, parser, namespace, values, option_string=None):
t1 = subprocess.run("docker container ps", capture_output=True, shell=True, text=True, check=True)
l = {}
t = ()
print("***********************")
for line in t1.stdout.splitlines():
r = re.findall(r'\S+',line)
if (r[0] != "CONTAINER"):
t2 = subprocess.run("docker inspect --format='{{{{.Config.Image}}}}' {}".format(r[0]), capture_output=True, shell=True, text=True, check=True)
#print(t2)
if ((t2.stdout) == "\n"):
t2.stdout = "Error"
inc = inc+1
t3 = t2.stdout
l[(r[0])] = t3.rstrip()

values=l
print("The list of Containers running in the box and its repo-tag..")
print(values)
setattr(namespace, self.dest, values)


if __name__ == '__main__':
parser = argparse.ArgumentParser(description='A python code to display argparse capability', fromfile_prefix_chars='@', argument_default=argparse.SUPPRESS, epilog='Hope you like this program')

#parser.add_argument('-s', type=findsh4, help='to display the image sha4')
parser.add_argument('-img', type=count1, nargs='?', const='c', help='to display the total images in the box')
parser.add_argument('-ctan', type=count2, nargs='?', const='c', help='to display the total containers in the box')
parser.add_argument('-sha', type=Findsha, nargs=1, help='to display the sha layers for an image-id in the box')
#parser.add_argument('-sha', type=Findsha, nargs='1', const='c', help='to display the image sha in the box')
parser.add_argument('-dstat', action=docklist, const='l', help='to display the list Docker daemon running')
parser.add_argument('-il', action=Imagelist, help='to display the list of images and if they are DANGLING')
#parser.add_argument('-ir', action=ImageRepo, help='to display the list of container iamges repo details')
parser.add_argument('-cl', action=Containerlist, help='to display the list of containers in this box')
args = parser.parse_args()

If you have any issues, you can open an issue in the github repo page or alternatively contact me at rangapv@yahoo.com and you can also find me on X.com(twitter) @rangapv

--

--

Rangaswamy P V

Works on Devops in Startups, reach me @rangapv on X/twitter or email: rangapv@gmail.com