-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
855c1c5
commit af12302
Showing
6 changed files
with
224 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# | ||
# Copyright 2018-2024 Hugo López-Fernández, Pedro M. Ferreira, Miguel | ||
# Reboiro-Jato, Cristina P. Vieira, and Jorge Vieira | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
|
||
FROM pegi3s/docker | ||
|
||
RUN apt-get -y update | ||
RUN apt-get install -y python3 | ||
RUN apt-get install -y python3-tk | ||
COPY main.py /opt | ||
COPY manageDocker.py /opt | ||
WORKDIR /opt | ||
ENTRYPOINT ["python3", "main.py"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# This image belongs to a larger project called Bioinformatics Docker Images Project (http://pegi3s.github.io/dockerfiles) | ||
## (Please note that the original software licenses still apply) | ||
|
||
This image facilitates the usage of docker-manager, a program with a graphical interface for managing Docker images. | ||
|
||
# Using the docker-manager image in Linux | ||
You should run the following command: `docker run --rm -ti -e USERID=$UID -e USER=$USER -e DISPLAY=$DISPLAY -v /var/db:/var/db:Z -v /tmp/.X11-unix:/tmp/.X11-unix -v $HOME/.Xauthority:/home/developer/.Xauthority -v /var/run/docker.sock:/var/run/docker.sock -v /tmp:/tmp pegi3s/docker-manager` | ||
|
||
Because of its graphical interface you must run the `xhost +` command first. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
import subprocess | ||
import tkinter as tk | ||
from tkinter import ttk | ||
from manageDocker import delete_docker_image, get_docker_images | ||
|
||
def show_toast(instruction): | ||
toast = tk.Toplevel() | ||
toast.title("Toast") | ||
toast.geometry("300x100") | ||
tk.Label(toast, text=instruction, font=("Helvetica", 12)).pack(pady=20) | ||
toast.after(2000, toast.destroy) # Close the toast after 2 seconds (2000 milliseconds) | ||
|
||
def delete_item(item_id): | ||
my_tree.delete(item_id) | ||
|
||
def on_delete_button_click(item_id): | ||
delete_item(item_id) | ||
|
||
def is_image_in_use(image_id): | ||
try: | ||
subprocess.run(f"docker inspect {image_id}", shell=True, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | ||
return True # Image is in use | ||
except subprocess.CalledProcessError as e: | ||
return False # Image is not in use | ||
|
||
def delete_selected_item(): | ||
selected_items = my_tree.selection() | ||
for item_id in selected_items: | ||
image_id = my_tree.item(item_id, "values")[1] # Get the Image ID from the selected item | ||
if delete_docker_image(image_id): | ||
delete_item(item_id) # Delete the item from the Treeview if the image was deleted | ||
|
||
def refresh_treeview(): | ||
# Clear the existing items in the Treeview | ||
for item in my_tree.get_children(): | ||
my_tree.delete(item) | ||
|
||
# Fetch Docker images and populate the Treeview | ||
docker_images = get_docker_images() | ||
for image in docker_images: | ||
status = is_image_in_use(image["IMAGE ID"]) | ||
item_id = my_tree.insert("", "end", values=(image["REPOSITORY"], image["IMAGE ID"], image["CREATED"], image["SIZE"], status)) | ||
|
||
def delete_unused_images(): | ||
docker_images = get_docker_images() | ||
for image in docker_images: | ||
status = is_image_in_use(image["IMAGE ID"]) | ||
if not status: # If the image is not in use, delete it | ||
delete_docker_image(image["IMAGE ID"]) | ||
|
||
refresh_treeview() # Refresh the Treeview after deleting unused images | ||
|
||
# Create the main window | ||
window = tk.Tk() | ||
window.title("Manage Docker Images") | ||
window.geometry("1000x500") | ||
|
||
# Add text above the Treeview | ||
title_label = tk.Label(window, text="Manage Docker Images", font=("Helvetica", 25)) | ||
title_label.pack(pady=20) | ||
|
||
# Create a frame to hold the Treeview and the vertical scrollbar | ||
tree_frame = tk.Frame(window) | ||
tree_frame.pack(expand=True, fill=tk.BOTH, padx=10, pady=10) | ||
|
||
# Create a Treeview for displaying items | ||
my_tree = ttk.Treeview(tree_frame, columns=("Name", "ID", "Date", "Size", "Status"), show="headings", height=14) | ||
my_tree.heading("Name", text="Name") | ||
my_tree.heading("ID", text="Image ID") | ||
my_tree.heading("Date", text="Date") | ||
my_tree.heading("Size", text="Size") | ||
my_tree.heading("Status", text="Status") | ||
my_tree.column("Name", width=200, anchor="center") | ||
my_tree.column("ID", width=150, anchor="center") | ||
my_tree.column("Date", width=150, anchor="center") | ||
my_tree.column("Size", width=100, anchor="center") | ||
my_tree.column("Status", width=100, anchor="center") | ||
|
||
|
||
|
||
# Fetch Docker images and populate the Treeview | ||
docker_images = get_docker_images() | ||
for image in docker_images: | ||
status = is_image_in_use(image["IMAGE ID"]) | ||
item_id = my_tree.insert("", "end", values=(image["REPOSITORY"], image["IMAGE ID"], image["CREATED"], image["SIZE"], status)) | ||
|
||
# Create a vertical scrollbar | ||
vsb = ttk.Scrollbar(tree_frame, orient="vertical", command=my_tree.yview) | ||
my_tree.configure(yscrollcommand=vsb.set) | ||
vsb.pack(side="right", fill="y") | ||
|
||
# Increase the width of the entire treeview | ||
my_tree.pack(expand=True, fill="both") | ||
|
||
# Create a frame for buttons at the bottom | ||
button_frame = tk.Frame(window) | ||
button_frame.pack(pady=10) | ||
|
||
refreshButton = tk.Button(button_frame, text="Refresh", command=refresh_treeview) | ||
deleteUnusedImagesButton = tk.Button(button_frame, text="Delete Unused Images", command=delete_unused_images) | ||
delete_button = tk.Button(button_frame, text="Delete Selected", command=delete_selected_item) | ||
|
||
refreshButton.pack(side="left", padx=10) | ||
deleteUnusedImagesButton.pack(side="left", padx=10) | ||
delete_button.pack(side="left", padx=10) | ||
|
||
|
||
window.mainloop() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import subprocess | ||
|
||
def get_docker_images(): | ||
try: | ||
# Run the "docker image list" command and capture the output | ||
result = subprocess.run("docker image list", shell=True, capture_output=True, text=True, check=True) | ||
|
||
# The output of the command is stored in the 'stdout' attribute of the 'result' object | ||
docker_images_output = result.stdout | ||
|
||
# Split the input string into lines and skip the header line | ||
lines = docker_images_output.strip().split('\n')[1:] | ||
|
||
# Create a list to store image details | ||
docker_images = [] | ||
|
||
# Iterate through the lines and create objects for each image | ||
for line in lines: | ||
parts = line.split() | ||
image_id = parts[2] # Image ID is at index 2 | ||
repository = parts[0] | ||
created = parts[4] + " " + parts[5] # Combine the "CREATED" and "TIME AGO" columns | ||
size = parts[6] | ||
|
||
# Create a dictionary for each image and add it to the list | ||
docker_image = { | ||
"IMAGE ID": image_id, | ||
"REPOSITORY": repository, | ||
"CREATED": created, | ||
"SIZE": size | ||
} | ||
docker_images.append(docker_image) | ||
|
||
return docker_images | ||
except subprocess.CalledProcessError as e: | ||
print("Error:", e) | ||
|
||
def check_images_usage(image_list): | ||
image_status = {} | ||
|
||
for image in image_list: | ||
image_id = image["IMAGE ID"] | ||
is_used = is_image_in_use(image_id) | ||
image_status[image_id] = is_used | ||
|
||
return image_status | ||
|
||
def is_image_in_use(image_id): | ||
try: | ||
subprocess.run(f"docker inspect {image_id}", shell=True, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | ||
return True # Image exists and can be inspected, so it's in use | ||
except subprocess.CalledProcessError as e: | ||
return False # Image does not exist, so it's not in use | ||
|
||
def delete_docker_image(image_id): | ||
try: | ||
subprocess.run(f"docker rmi -f {image_id}", shell=True, check=True) | ||
return True | ||
except subprocess.CalledProcessError as e: | ||
print("Error:", e) | ||
return False |