aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorDanilo Segan <danilo@canonical.com>2012-08-23 01:31:27 +0200
committerDanilo Segan <danilo@canonical.com>2012-08-23 01:31:27 +0200
commit832359b6fd5ad7b61e4f1b39f678a27908ab7be9 (patch)
treece3d54cccddb0c04745f50556bd2623cabd662d6 /scripts
parenta08499777e67f7a42c9ba9fa7f2f927237e951b9 (diff)
Add the script to create a very bare sanitized tree.
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/make-sanitized-tree-copy.py96
1 files changed, 96 insertions, 0 deletions
diff --git a/scripts/make-sanitized-tree-copy.py b/scripts/make-sanitized-tree-copy.py
new file mode 100755
index 0000000..af45ee9
--- /dev/null
+++ b/scripts/make-sanitized-tree-copy.py
@@ -0,0 +1,96 @@
+#!/usr/bin/env python
+# Create a copy of a directory structure while preserving as much metadata
+# as possible and sanitizing any sensitive data.
+
+# Everything, unless whitelisted, is truncated and the contents are replaced
+# with the base file name itself.
+
+import os
+import shutil
+import tempfile
+
+from linaroscript import LinaroScript
+from publish_to_snapshots import SnapshotsPublisher
+
+
+class MakeSanitizedTreeCopyScript(LinaroScript):
+
+ def setup_parser(self):
+ super(MakeSanitizedTreeCopyScript, self).setup_parser()
+ self.argument_parser.add_argument(
+ 'directory', metavar='DIR', type=str,
+ help="Directory to create a sanitized deep copy of.")
+
+ @staticmethod
+ def filter_accepted_files(directory, list_of_files):
+ accepted_files = []
+ for filename in list_of_files:
+ full_path = os.path.join(directory, filename)
+ if SnapshotsPublisher.is_accepted_for_staging(full_path):
+ accepted_files.append(filename)
+ return accepted_files
+
+ def copy_sanitized_tree(self, source, target):
+ """Copies the tree from `source` to `target` while sanitizing it.
+
+ Performs a recursive copy trying to preserve as many file
+ attributes as possible.
+ """
+ assert os.path.isdir(source) and os.path.isdir(target), (
+ "Both source (%s) and target (%s) must be directories." % (
+ source, target))
+ self.logger.debug("copy_sanitized_tree('%s', '%s')", source, target)
+ filenames = os.listdir(source)
+ for filename in filenames:
+ self.logger.debug("Copying '%s'...", filename)
+ source_file = os.path.join(source, filename)
+ target_file = os.path.join(target, filename)
+ try:
+ if os.path.isdir(source_file):
+ self.logger.debug("Making directory '%s'" % target_file)
+ os.makedirs(target_file)
+ self.copy_sanitized_tree(source_file, target_file)
+ elif SnapshotsPublisher.is_accepted_for_staging(source_file):
+ self.logger.debug(
+ "Copying '%s' to '%s' with no sanitization...",
+ source_file, target_file)
+ shutil.copy2(source_file, target_file)
+ else:
+ self.logger.debug(
+ "Creating sanitized file '%s'", target_file)
+ # This creates an target file.
+ open(target_file, "w").close()
+ shutil.copystat(source_file, target_file)
+ SnapshotsPublisher.sanitize_file(target_file)
+ except (IOError, os.error) as why:
+ self.logger.error(
+ "While copying '%s' to '%s' we hit:\n\t%s",
+ source_file, target_file, str(why))
+
+ try:
+ shutil.copystat(source, target)
+ except OSError as why:
+ self.logger.error(
+ "While copying '%s' to '%s' we hit:\n\t%s",
+ source, target, str(why))
+
+ def work(self):
+ source_directory = self.arguments.directory
+ self.logger.info("Copying and sanitizing '%s'...", source_directory)
+ target_directory = tempfile.mkdtemp()
+ self.logger.info("Temporary directory: '%s'", target_directory)
+
+ self.copy_sanitized_tree(
+ self.arguments.directory, target_directory)
+
+ print target_directory
+
+if __name__ == '__main__':
+ script = MakeSanitizedTreeCopyScript(
+ 'make-sanitized-tree-copy',
+ description=(
+ "Makes a copy of a directory tree in a temporary location "
+ "and sanitize file that can contain potentially restricted "
+ "content. "
+ "Returns the path of a newly created temporary directory."))
+ script.run()