docker-diff 0.0.1__py3-none-any.whl → 0.0.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: docker-diff
3
- Version: 0.0.1
3
+ Version: 0.0.3
4
4
  Summary: Docker Image Comparison Database Manager
5
5
  License: This is free and unencumbered software released into the public domain.
6
6
 
@@ -0,0 +1,10 @@
1
+ docker_diff-0.0.3.dist-info/licenses/LICENSE,sha256=awOCsWJ58m_2kBQwBUGWejVqZm6wuRtCL2hi9rfa0X4,1211
2
+ docker_diff_pkg/__init__.py,sha256=aG5WUO74Z5ax04A5iwh6thCpHcFXBsdH5v-ph-uUJuI,321
3
+ docker_diff_pkg/_version.py,sha256=pBZsQt6tlL02W-ri--X_4JCubpAK7jjCSnOmUp_isjc,704
4
+ docker_diff_pkg/cli.py,sha256=iXC5GR1jCzhmJpFCSJHSujL3vdAkXQOpeOtBJYGQy_A,15983
5
+ docker_diff_pkg/schema.sql,sha256=xI3kOohbUEzwFhmIGQs2_abN_tJn1BBdAya7tVbw6n8,5477
6
+ docker_diff-0.0.3.dist-info/METADATA,sha256=tD-HCOW5qF_BWaoB6LIAeP3Om4AmxJo7hXHgm0Q1XCg,1654
7
+ docker_diff-0.0.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
8
+ docker_diff-0.0.3.dist-info/entry_points.txt,sha256=nEDTWZsgB5fRJgeXHJbXJyaHKMmKyN9Qypf3X78tosw,57
9
+ docker_diff-0.0.3.dist-info/top_level.txt,sha256=GB5Qrc3AH1pk0543cQz9SRNr5Fatrj-c0Cdp3rCvTM8,16
10
+ docker_diff-0.0.3.dist-info/RECORD,,
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ docker-diff = docker_diff_pkg.cli:main
@@ -0,0 +1 @@
1
+ docker_diff_pkg
@@ -0,0 +1,10 @@
1
+ """
2
+ Docker Image Comparison Database Manager
3
+ Provides functions to store and query Docker image file comparison results in SQLite
4
+ """
5
+
6
+ from .cli import DockerImageDB, main
7
+ try:
8
+ from ._version import version as __version__
9
+ except Exception: # pragma: no cover - fallback for editable/no-scm
10
+ __version__ = "0.0.0"
@@ -0,0 +1,34 @@
1
+ # file generated by setuptools-scm
2
+ # don't change, don't track in version control
3
+
4
+ __all__ = [
5
+ "__version__",
6
+ "__version_tuple__",
7
+ "version",
8
+ "version_tuple",
9
+ "__commit_id__",
10
+ "commit_id",
11
+ ]
12
+
13
+ TYPE_CHECKING = False
14
+ if TYPE_CHECKING:
15
+ from typing import Tuple
16
+ from typing import Union
17
+
18
+ VERSION_TUPLE = Tuple[Union[int, str], ...]
19
+ COMMIT_ID = Union[str, None]
20
+ else:
21
+ VERSION_TUPLE = object
22
+ COMMIT_ID = object
23
+
24
+ version: str
25
+ __version__: str
26
+ __version_tuple__: VERSION_TUPLE
27
+ version_tuple: VERSION_TUPLE
28
+ commit_id: COMMIT_ID
29
+ __commit_id__: COMMIT_ID
30
+
31
+ __version__ = version = '0.0.3'
32
+ __version_tuple__ = version_tuple = (0, 0, 3)
33
+
34
+ __commit_id__ = commit_id = None
@@ -20,10 +20,18 @@ class DockerImageDB:
20
20
  def init_database(self):
21
21
  """Initialize the database with schema"""
22
22
  with sqlite3.connect(self.db_path) as conn:
23
- # Read and execute schema
24
- schema_path = Path(__file__).parent / "schema.sql"
25
- with open(schema_path) as f:
26
- conn.executescript(f.read())
23
+ # Read schema using importlib.resources for proper packaging
24
+ try:
25
+ import importlib.resources as pkg_resources
26
+ with pkg_resources.files('docker_diff_pkg').joinpath('schema.sql').open('r') as f:
27
+ schema_content = f.read()
28
+ except (ImportError, AttributeError):
29
+ # Fallback for Python < 3.9
30
+ import importlib_resources as pkg_resources
31
+ with pkg_resources.files('docker_diff_pkg').joinpath('schema.sql').open('r') as f:
32
+ schema_content = f.read()
33
+
34
+ conn.executescript(schema_content)
27
35
 
28
36
  def add_image(self, name: str, digest: str = None, size_bytes: int = None) -> int:
29
37
  """Add an image to the database, return image_id"""
@@ -0,0 +1,138 @@
1
+ -- SQLite schema for Docker image file comparison results
2
+ -- This database stores file listings and comparison results across multiple images
3
+
4
+ -- Table to store unique images being analyzed
5
+ CREATE TABLE IF NOT EXISTS images (
6
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
7
+ name TEXT NOT NULL UNIQUE, -- e.g., 'ubuntu:20.04'
8
+ digest TEXT, -- SHA256 digest if available
9
+ size_bytes INTEGER, -- Total image size
10
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
11
+ scanned_at DATETIME DEFAULT CURRENT_TIMESTAMP
12
+ );
13
+
14
+ -- Table to store files found in each image
15
+ CREATE TABLE IF NOT EXISTS files (
16
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
17
+ image_id INTEGER NOT NULL,
18
+ file_path TEXT NOT NULL, -- Full path: /usr/bin/curl
19
+ file_size INTEGER, -- Size in bytes
20
+ file_mode TEXT, -- File permissions (optional)
21
+ modified_time INTEGER, -- Unix timestamp
22
+ file_type TEXT DEFAULT 'file', -- 'file', 'directory', 'symlink'
23
+ checksum TEXT, -- MD5/SHA256 if calculated
24
+ FOREIGN KEY (image_id) REFERENCES images(id) ON DELETE CASCADE,
25
+ UNIQUE(image_id, file_path)
26
+ );
27
+
28
+ -- Table to store comparison sessions
29
+ CREATE TABLE IF NOT EXISTS comparisons (
30
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
31
+ name TEXT, -- Optional comparison name
32
+ description TEXT, -- Optional description
33
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP
34
+ );
35
+
36
+ -- Junction table linking images to comparisons
37
+ CREATE TABLE IF NOT EXISTS comparison_images (
38
+ comparison_id INTEGER NOT NULL,
39
+ image_id INTEGER NOT NULL,
40
+ FOREIGN KEY (comparison_id) REFERENCES comparisons(id) ON DELETE CASCADE,
41
+ FOREIGN KEY (image_id) REFERENCES images(id) ON DELETE CASCADE,
42
+ PRIMARY KEY (comparison_id, image_id)
43
+ );
44
+
45
+ -- Table to store file differences between images
46
+ CREATE TABLE IF NOT EXISTS file_differences (
47
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
48
+ comparison_id INTEGER NOT NULL,
49
+ file_path TEXT NOT NULL,
50
+ difference_type TEXT NOT NULL, -- 'added', 'removed', 'modified', 'common'
51
+ source_image_id INTEGER, -- Image where file exists/existed
52
+ target_image_id INTEGER, -- Image being compared to
53
+ old_size INTEGER, -- Previous size (for modified files)
54
+ new_size INTEGER, -- New size (for modified files)
55
+ size_change INTEGER, -- Calculated: new_size - old_size
56
+ FOREIGN KEY (comparison_id) REFERENCES comparisons(id) ON DELETE CASCADE,
57
+ FOREIGN KEY (source_image_id) REFERENCES images(id),
58
+ FOREIGN KEY (target_image_id) REFERENCES images(id)
59
+ );
60
+
61
+ -- Table for summary statistics per comparison
62
+ CREATE TABLE IF NOT EXISTS comparison_stats (
63
+ comparison_id INTEGER PRIMARY KEY,
64
+ total_files_compared INTEGER,
65
+ files_added INTEGER,
66
+ files_removed INTEGER,
67
+ files_modified INTEGER,
68
+ files_common INTEGER,
69
+ total_size_change INTEGER, -- Net size change in bytes
70
+ largest_file_added TEXT, -- Path to largest added file
71
+ largest_file_removed TEXT, -- Path to largest removed file
72
+ FOREIGN KEY (comparison_id) REFERENCES comparisons(id) ON DELETE CASCADE
73
+ );
74
+
75
+ -- Indexes for better query performance
76
+ CREATE INDEX IF NOT EXISTS idx_files_image_id ON files(image_id);
77
+ CREATE INDEX IF NOT EXISTS idx_files_path ON files(file_path);
78
+ CREATE INDEX IF NOT EXISTS idx_files_size ON files(file_size);
79
+ CREATE INDEX IF NOT EXISTS idx_differences_comparison ON file_differences(comparison_id);
80
+ CREATE INDEX IF NOT EXISTS idx_differences_type ON file_differences(difference_type);
81
+ CREATE INDEX IF NOT EXISTS idx_differences_path ON file_differences(file_path);
82
+
83
+ -- Views for common queries
84
+
85
+ -- View: Files unique to each image in a comparison
86
+ CREATE VIEW IF NOT EXISTS unique_files AS
87
+ SELECT
88
+ c.name as comparison_name,
89
+ i.name as image_name,
90
+ f.file_path,
91
+ f.file_size,
92
+ 'unique' as status
93
+ FROM files f
94
+ JOIN images i ON f.image_id = i.id
95
+ JOIN comparison_images ci ON i.id = ci.image_id
96
+ JOIN comparisons c ON ci.comparison_id = c.id
97
+ WHERE f.file_path NOT IN (
98
+ SELECT DISTINCT f2.file_path
99
+ FROM files f2
100
+ JOIN comparison_images ci2 ON f2.image_id = ci2.image_id
101
+ WHERE ci2.comparison_id = ci.comparison_id
102
+ AND f2.image_id != f.image_id
103
+ );
104
+
105
+ -- View: Files common across all images in a comparison
106
+ CREATE VIEW IF NOT EXISTS common_files AS
107
+ SELECT
108
+ c.name as comparison_name,
109
+ f.file_path,
110
+ COUNT(DISTINCT f.image_id) as image_count,
111
+ MIN(f.file_size) as min_size,
112
+ MAX(f.file_size) as max_size,
113
+ AVG(f.file_size) as avg_size
114
+ FROM files f
115
+ JOIN images i ON f.image_id = i.id
116
+ JOIN comparison_images ci ON i.id = ci.image_id
117
+ JOIN comparisons c ON ci.comparison_id = c.id
118
+ GROUP BY c.id, f.file_path
119
+ HAVING COUNT(DISTINCT f.image_id) = (
120
+ SELECT COUNT(*)
121
+ FROM comparison_images ci2
122
+ WHERE ci2.comparison_id = c.id
123
+ );
124
+
125
+ -- View: Size comparison between images
126
+ CREATE VIEW IF NOT EXISTS image_sizes AS
127
+ SELECT
128
+ c.name as comparison_name,
129
+ i.name as image_name,
130
+ COUNT(f.id) as file_count,
131
+ SUM(f.file_size) as total_file_size,
132
+ AVG(f.file_size) as avg_file_size,
133
+ MAX(f.file_size) as largest_file_size
134
+ FROM images i
135
+ JOIN files f ON i.id = f.image_id
136
+ JOIN comparison_images ci ON i.id = ci.image_id
137
+ JOIN comparisons c ON ci.comparison_id = c.id
138
+ GROUP BY c.id, i.id;
@@ -1,7 +0,0 @@
1
- docker_diff.py,sha256=_Jt20fhQqZQGac-PacGyV9IU10FXNoCrc6lqlZe4Gps,15516
2
- docker_diff-0.0.1.dist-info/licenses/LICENSE,sha256=awOCsWJ58m_2kBQwBUGWejVqZm6wuRtCL2hi9rfa0X4,1211
3
- docker_diff-0.0.1.dist-info/METADATA,sha256=XnO5IBtAKuZq0xQ8C45jYB445OD91_xdzrTnsfh0Ktc,1654
4
- docker_diff-0.0.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
5
- docker_diff-0.0.1.dist-info/entry_points.txt,sha256=Hknxh2UZBgBH5Lwe55BK5Gh813R1qHZSPIYQ9dzKQXk,49
6
- docker_diff-0.0.1.dist-info/top_level.txt,sha256=HSDBG4y8znoDTP5jcUCH2gZZ-qiZW0_6AsIeXry71Ew,12
7
- docker_diff-0.0.1.dist-info/RECORD,,
@@ -1,2 +0,0 @@
1
- [console_scripts]
2
- docker-diff = docker_diff:main
@@ -1 +0,0 @@
1
- docker_diff