~rjarry/dlrepo

18c4878d4d2a81ff4e7e356525297c8cbdc4d2ef — Julien Floret 1 year, 2 months ago bcfcf65
job: detect product link conflicts

Several jobs may be linked to the same product. For example,
we can have a job handling the generation of the binary packages (a
"bin" format), and another job handling the generation of the
documentation (a "doc" format) for the same product.

However, if some formats of the two jobs overlap (e.g. each job has a
"bin" format), the product format will point to the latest uploaded
job. This usually happens if there is a mistake in the declaration of
the product variant of one of the jobs.
However, since there is no error, the conflict can easily be missed.

To avoid this, when updating the symlinks, let symlink_to() throw an
exception if the link already exists. The dlrepo-cli "set-info"
command will then return an error and it will be easier to detect the
conflict. Rename the update_symlink() method to reflect the change.

Note that this works because we should never have to update an
existing link: in set_metadata(), the current links are removed
before creating the new links.

Signed-off-by: Julien Floret <julien.floret@6wind.com>
Acked-by: Thomas Faivre <thomas.faivre@6wind.com>
1 files changed, 3 insertions(+), 9 deletions(-)

M dlrepo/fs/job.py
M dlrepo/fs/job.py => dlrepo/fs/job.py +3 -9
@@ 3,7 3,6 @@
# SPDX-License-Identifier: BSD-3-Clause

import asyncio
import errno
import hashlib
import json
import logging


@@ 82,12 81,7 @@ class Job(SubDir):
            path.unlink()

    @staticmethod
    def update_symlink(dst, link):
        if link.exists():
            if link.is_symlink():
                link.unlink()
            else:
                raise OSError(errno.ENOTEMPTY, f"{link} exists and is not a symlink")
    def create_symlink(dst, link):
        link.symlink_to(os.path.relpath(dst, link.parent))

    def _link_to_product(self, version: Version):


@@ 107,9 101,9 @@ class Job(SubDir):
        The formats in a product version are not necessarily linked to the same job.
        """
        version.create()
        self.update_symlink(version.path(), self._product_link_path())
        self.create_symlink(version.path(), self._product_link_path())
        for fmt in self.get_formats():
            self.update_symlink(fmt.path(), version.path() / fmt.name)
            self.create_symlink(fmt.path(), version.path() / fmt.name)

    def _cleanup_product_tree(self):
        link = self._product_link_path()