diff --git a/.github/workflows/squash.yml b/.github/workflows/squash.yml index 0aa167a..a34b457 100644 --- a/.github/workflows/squash.yml +++ b/.github/workflows/squash.yml @@ -64,3 +64,30 @@ jobs: PV=${{ matrix.python-version }} echo "Running tests for Python version $PV ( ${PV/./} )" make test-py"${PV/./}" + build-podman-3: + runs-on: ubuntu-20.04 + strategy: + fail-fast: false + matrix: + python-version: ['3.6', '3.7', '3.8', '3.9', '3.10', '3.11', '3.12'] + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Setup + run: | + sudo apt-get update + pip install "tox<4.0.0" setuptools + - name: Info + run: | + podman version + podman info + - name: Run tests + run: | + systemctl --user start podman.socket + export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/podman/podman.sock + PV=${{ matrix.python-version }} + echo "Running tests for Python version $PV ( ${PV/./} )" + make test-py"${PV/./}" diff --git a/.gitignore b/.gitignore index 75187ff..66e519a 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ target .idea .venv docker-squash.iml +**/image.tar +**/tox.tar diff --git a/Pipfile b/Pipfile index e1b5731..3276944 100644 --- a/Pipfile +++ b/Pipfile @@ -10,6 +10,7 @@ docker = "*" pytest = "*" pytest-cov = "*" mock = "*" +parameterized = "*" twine = "*" isort = "*" black = "*" diff --git a/docker_squash/v2_image.py b/docker_squash/v2_image.py index 861b0bd..3baee28 100644 --- a/docker_squash/v2_image.py +++ b/docker_squash/v2_image.py @@ -16,6 +16,9 @@ class V2Image(Image): def _before_squashing(self): super(V2Image, self)._before_squashing() + # New OCI Archive format type + self.oci_format = True + # Read old image manifest file self.old_image_manifest = self._get_manifest() self.log.debug( @@ -375,8 +378,6 @@ def _generate_image_metadata(self): def _get_manifest(self): if os.path.exists(os.path.join(self.old_image_dir, "index.json")): - # New OCI Archive format type - self.oci_format = True # Not using index.json to extract manifest details as while the config # sha could be extracted via some indirection i.e. # diff --git a/tests/test_integ_squash.py b/tests/test_integ_squash.py index 1a2245d..930b581 100644 --- a/tests/test_integ_squash.py +++ b/tests/test_integ_squash.py @@ -13,6 +13,7 @@ import mock import pytest from packaging import version as packaging_version +from parameterized import parameterized from docker_squash.errors import SquashError, SquashUnnecessaryError from docker_squash.lib import common @@ -37,7 +38,7 @@ def top_layer_path(tar): class IntegSquash(unittest.TestCase): - BUSYBOX_IMAGE = "busybox:1.34" + BUSYBOX_IMAGE = "busybox:1.36.1" log = logging.getLogger() handler = logging.StreamHandler() @@ -698,7 +699,7 @@ def test_handle_correctly_squashing_layers_without_data(self): ) with self.Image(dockerfile) as image: - with self.SquashedImage(image, 2) as squashed_image: + with self.SquashedImage(image, 2, numeric=True) as squashed_image: self.assertEqual(len(squashed_image.layers), len(image.layers) - 1) image_data_layers = [s for s in image.tarnames if "layer.tar" in s] squashed_image_data_layers = [ @@ -735,7 +736,7 @@ def test_should_squash_exactly_2_layers_without_data(self): ) with self.Image(dockerfile) as image: - with self.SquashedImage(image, 2) as squashed_image: + with self.SquashedImage(image, 2, numeric=True) as squashed_image: self.assertEqual(len(squashed_image.layers), len(image.layers) - 1) def test_should_squash_exactly_3_layers_with_data(self): @@ -757,9 +758,9 @@ def test_should_not_squash_if_only_one_layer_is_to_squash(self): dockerfile = ( """ FROM %s - RUN touch /abc CMD /bin/env LABEL foo bar + RUN touch /abc """ % TestIntegSquash.BUSYBOX_IMAGE ) @@ -796,7 +797,7 @@ def test_should_squash_every_layer(self): def test_remove_tmp_dir_after_failure(self): self.caplog.set_level(logging.DEBUG, logger="cekit") dockerfile = """ - FROM busybox:1.24.0 + FROM busybox:1.36.1 LABEL foo bar """ @@ -820,7 +821,7 @@ def test_remove_tmp_dir_after_failure(self): def test_should_not_remove_tmp_dir_after_failure_if_development_mode_is_on(self): dockerfile = """ - FROM busybox:1.24.0 + FROM busybox:1.36.1 LABEL foo bar """ @@ -1261,7 +1262,7 @@ class NumericValues(IntegSquash): @classmethod def setUpClass(cls): dockerfile = """ - FROM busybox:1.24.0 + FROM busybox:1.36.1 RUN touch /tmp/test1 RUN touch /tmp/test2 CMD /bin/env @@ -1306,41 +1307,24 @@ def test_should_not_squash_single_layer(self): with self.SquashedImage(NumericValues.image, 1, numeric=True): pass - def test_should_squash_2_layers(self): - with self.SquashedImage(NumericValues.image, 2, numeric=True) as squashed_image: - i_h = NumericValues.image.history[0] - s_h = squashed_image.history[0] + @parameterized.expand([(2,), (3,), (4,)]) + def test_should_squash_n_layers(self, number_of_layers): + with self.SquashedImage( + NumericValues.image, number_of_layers, numeric=True + ) as squashed_image: + i_h = NumericValues.image.history[number_of_layers:] + s_h = squashed_image.history[1:] - for key in "Comment", "Size": - self.assertEqual(i_h[key], s_h[key]) - self.assertEqual(s_h["CreatedBy"], "") self.assertEqual( - len(squashed_image.layers), len(NumericValues.image.layers) - 1 + len(squashed_image.layers), + len(NumericValues.image.layers) - (number_of_layers - 1), ) - def test_should_squash_3_layers(self): - with self.SquashedImage(NumericValues.image, 3, numeric=True) as squashed_image: - i_h = NumericValues.image.history[0] - s_h = squashed_image.history[0] - - for key in "Comment", "Size": - self.assertEqual(i_h[key], s_h[key]) - self.assertEqual(s_h["CreatedBy"], "") - self.assertEqual( - len(squashed_image.layers), len(NumericValues.image.layers) - 2 - ) - - def test_should_squash_4_layers(self): - with self.SquashedImage(NumericValues.image, 4, numeric=True) as squashed_image: - i_h = NumericValues.image.history[0] - s_h = squashed_image.history[0] - - for key in "Comment", "Size": - self.assertEqual(i_h[key], s_h[key]) - self.assertEqual(s_h["CreatedBy"], "") - self.assertEqual( - len(squashed_image.layers), len(NumericValues.image.layers) - 3 - ) + for c in range(len(i_h)): + for key in "CreatedBy", "Comment", "Size": + self.assertEqual(s_h[c][key], i_h[c][key]) + self.assertEqual(squashed_image.history[0]["Comment"], "") + self.assertEqual(squashed_image.history[0]["CreatedBy"], "") if __name__ == "__main__":