From e38dffa2ff65c41ee446037a6f7a783f85f3a422 Mon Sep 17 00:00:00 2001 From: Adam Coldrick Date: Tue, 14 Apr 2015 15:00:58 +0000 Subject: fixup: Fixes to ostreeartifactcache --- morphlib/ostreeartifactcache.py | 60 +++++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/morphlib/ostreeartifactcache.py b/morphlib/ostreeartifactcache.py index f0fd6b56..230460f8 100644 --- a/morphlib/ostreeartifactcache.py +++ b/morphlib/ostreeartifactcache.py @@ -18,6 +18,7 @@ import collections import contextlib import logging import os +import stat import shutil import tarfile import tempfile @@ -103,6 +104,24 @@ class OSTreeArtifactCache(object): filename = self.artifact_filename(artifact) shutil.copy(location, filename) + def _remove_device_nodes(self, path): + for dirpath, dirnames, filenames in os.walk(path): + for f in filenames: + filepath = os.path.join(dirpath, f) + mode = os.lstat(filepath).st_mode + if stat.S_ISBLK(mode) or stat.S_ISCHR(mode): + logging.debug('Removing device node %s from artifact' % + filepath) + os.remove(filepath) + + def _copy_metadata_from_remote(self, artifact, remote): + """Copy a metadata file from a remote cache.""" + a, name = artifact.basename().split('.', 1) + with self._get_file_from_remote(ArtifactCacheReference(a), + remote, name) as location: + self.put_non_ostree_artifact(ArtifactCacheReference(a), + location, name) + def copy_from_remote(self, artifact, remote): """Get 'artifact' from remote artifact cache and store it locally. @@ -112,21 +131,29 @@ class OSTreeArtifactCache(object): """ if remote.method == 'tarball': with self._get_file_from_remote(artifact, remote) as location: - if artifact.basename().split('.', 2)[1] == 'stratum': + try: + cache_key, kind, name = artifact.basename().split('.', 2) + except ValueError: + # We can't split the name properly, it must be metadata! + self._copy_metadata_from_remote(artifact, remote) + return + + if kind == 'stratum': self.put_non_ostree_artifact(artifact, location) + return try: tempdir = tempfile.mkdtemp(dir=self.cachedir) - try: - with tarfile.open(name=location) as tf: - tf.extractall(path=tempdir) - self.put(tempdir, artifact) - finally: - shutil.rmtree(tempdir) + with tarfile.open(name=location) as tf: + tf.extractall(path=tempdir) + self._remove_device_nodes(tempdir) + self.put(tempdir, artifact) except tarfile.ReadError: # Reading the tarball failed, and we expected a # tarball artifact. Something must have gone # wrong. raise + finally: + shutil.rmtree(tempdir) elif remote.method == 'ostree': self.status(msg='Pulling artifact for %(name)s from remote.', @@ -135,10 +162,7 @@ class OSTreeArtifactCache(object): ref = self._get_artifact_cache_name(artifact) except ValueError: # if we can't split the name properly, we must want metadata - a, name = artifact.basename().split('.', 1) - with self._get_file_from_remote(ArtifactCacheReference(a), - remote, name) as location: - self.put_non_ostree_artifact(artifact, location, name) + self._copy_metadata_from_remote(artifact, remote) return if artifact.basename().split('.', 2)[1] == 'stratum': @@ -204,14 +228,22 @@ class OSTreeArtifactCache(object): self.repo.prune() def has(self, artifact): - cachekey, kind, name = artifact.basename().split('.', 2) - logging.debug('OSTreeArtifactCache: checking for %s, %s, %s' % - (cachekey, kind, name)) + try: + cachekey, kind, name = artifact.basename().split('.', 2) + except ValueError: + # We couldn't split the basename properly, we must want metadata + cachekey, name = artifact.basename().split('.', 1) + if self.has_artifact_metadata(artifact, name): + return True + else: + return False + if kind == 'stratum': if self._has_file(self.artifact_filename(artifact)): return True else: return False + sha = self.repo.resolve_rev(self._get_artifact_cache_name(artifact)) if sha: self.repo.touch_ref(self._get_artifact_cache_name(artifact)) -- cgit v1.2.1