import io
import logging
import os.path
+import shutil
+import tempfile
import pakfire
def _write(self):
log.info("Writing repository %s..." % self)
+ # Write any new repositories to the temporary space first
+ tmp = self.backend.path("tmp")
+
# Create a new pakfire instance
- with self.pakfire() as p:
- for arch in self.arches:
+ with tempfile.TemporaryDirectory(dir=tmp, prefix="pakfire-repo-") as t:
+ with self.pakfire() as p:
+ for arch in self.arches:
+ # Destination path for this architecture
+ path = os.path.join(t, arch)
+
+ # Fetch packages
+ packages = self.get_packages(arch)
+
+ # Make filelist (if they exist)
+ files = [p.path for p in packages if os.path.exists(p.path)]
+
+ # Write repository metadata
+ p.repo_compose(path=path, files=files)
+
+ # Mark the repository as read-only
+ os.chmod(t, 0o755)
+
+ # Perform an atomic replace of the repository directory
+ with tempfile.TemporaryDirectory(dir=tmp, prefix="pakfire-repo-") as bin:
# Local path
- path = self.local_path(arch)
+ path = self.local_path()
- # Fetch packages
- packages = self.get_packages(arch)
+ # Move the old data to the temporary space
+ try:
+ shutil.move(path, bin)
- # Make filelist (if they exist)
- files = [p.path for p in packages if os.path.exists(p.path)]
+ # Ignore if this repository is being created for the first time
+ except FileNotFoundError:
+ pass
- # Write repository metadata
- p.repo_compose(path=path, files=files)
+ # Move the new repository data to its destination
+ shutil.move(t, path)