← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~julian-edwards/maas/add-fileserver into lp:maas

 

Julian Edwards has proposed merging lp:~julian-edwards/maas/add-fileserver into lp:maas.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~julian-edwards/maas/add-fileserver/+merge/92300
-- 
https://code.launchpad.net/~julian-edwards/maas/add-fileserver/+merge/92300
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~julian-edwards/maas/add-fileserver into lp:maas.
=== modified file 'src/maas/development.py'
--- src/maas/development.py	2012-02-09 07:43:25 +0000
+++ src/maas/development.py	2012-02-09 15:59:27 +0000
@@ -69,7 +69,7 @@
 
 # Absolute filesystem path to the directory that will hold user-uploaded files.
 # Example: "/home/media/media.lawrence.com/media/"
-MEDIA_ROOT = ''
+MEDIA_ROOT = '/var/tmp/maas/'
 
 # URL that handles the media served from MEDIA_ROOT. Make sure to use a
 # trailing slash.

=== modified file 'src/maasserver/models.py'
--- src/maasserver/models.py	2012-02-08 13:45:45 +0000
+++ src/maasserver/models.py	2012-02-09 15:59:27 +0000
@@ -23,6 +23,7 @@
 from django.contrib import admin
 from django.contrib.auth.backends import ModelBackend
 from django.contrib.auth.models import User
+from django.core.files.base import ContentFile
 from django.core.exceptions import PermissionDenied
 from django.db import models
 from django.db.models.signals import post_save
@@ -33,7 +34,6 @@
     Token,
     )
 
-
 class CommonInfo(models.Model):
     """A base model which records the creation date and the last modification
     date.
@@ -344,10 +344,40 @@
 post_save.connect(create_user, sender=User)
 
 
+class FileStorage(models.Model):
+    """A simple file storage keyed on file name.
+
+    :ivar filename: A unique file name to use for the data being stored.
+    :ivar data: The file's actual data.
+    """
+
+    filename = models.CharField(max_length=255, unique=True, editable=False)
+    data = models.FileField(upload_to="storage")
+
+    def __unicode__(self):
+        return self.filename
+
+    def save_file(self, filename, file_object):
+        """Save the file to the filesystem and persist to the database.
+
+        The file will end up in MEDIA_ROOT/storage/
+        """
+        self.filename = filename
+        # This probably ought to read in chunks but large files are
+        # unexpected.  Also note that uploading a file with the same
+        # name as an existing one will cause that file to be written
+        # with a new generated name, and the old one remains where it
+        # is.  See https://code.djangoproject.com/ticket/6157 - the
+        # Django devs consider deleting things dangerous ... ha.
+        content = ContentFile(file_object.read())
+        self.data.save(filename, content)
+
+
 # Register the models in the admin site.
+admin.site.register(Consumer)
+admin.site.register(FileStorage)
+admin.site.register(MACAddress)
 admin.site.register(Node)
-admin.site.register(MACAddress)
-admin.site.register(Consumer)
 
 
 class MaaSAuthorizationBackend(ModelBackend):

=== modified file 'src/maasserver/testing/factory.py'
--- src/maasserver/testing/factory.py	2012-01-24 15:25:49 +0000
+++ src/maasserver/testing/factory.py	2012-02-09 15:59:27 +0000
@@ -18,6 +18,7 @@
 
 from django.contrib.auth.models import User
 from maasserver.models import (
+    FileStorage,
     MACAddress,
     Node,
     NODE_STATUS,
@@ -66,6 +67,18 @@
         admin.save()
         return admin
 
+    def make_file_storage(self, filename=None, data=None):
+        if filename is None:
+            filename = self.getRandomString(255)
+        if data is None:
+            data = self.getRandomString(1024)
+
+        storage = FileStorage()
+        from StringIO import StringIO
+        storage.save_file(filename, StringIO(data))
+        storage.save()
+        return storage
+
 
 # Create factory singleton.
 factory = Factory()

=== modified file 'src/maasserver/tests/test_models.py'
--- src/maasserver/tests/test_models.py	2012-02-08 13:45:45 +0000
+++ src/maasserver/tests/test_models.py	2012-02-09 15:59:27 +0000
@@ -11,6 +11,9 @@
 __metaclass__ = type
 __all__ = []
 
+import os
+import shutil
+
 from django.core.exceptions import (
     PermissionDenied,
     ValidationError,
@@ -157,3 +160,31 @@
         self.assertIsInstance(tokens[0].key, unicode)
         self.assertEqual(KEY_SIZE, len(tokens[0].key))
         self.assertEqual(Token.ACCESS, tokens[0].token_type)
+
+
+class FileStorageTest(TestCase):
+    """Testing of the FileStorage model."""
+
+    FILEPATH = "/var/tmp/maas/"
+
+    def setUp(self):
+        super(FileStorageTest, self).setUp()
+        os.mkdir(self.FILEPATH)
+        self.addCleanup(shutil.rmtree, self.FILEPATH)
+
+    def test_creation(self):
+        storage = factory.make_file_storage(filename="myfile", data="mydata")
+        expected = ["myfile", "mydata"]
+        actual = [storage.filename, storage.data.read()]
+        self.assertEqual(expected, actual)
+
+    def test_creation_writes_a_file(self):
+        # The development settings say to write a file starting at
+        # /var/tmp, so check one is actually written there.  The field
+        # itself is hard-coded to make a directory called "storage".
+        storage = factory.make_file_storage(filename="myfile", data="mydata")
+
+        expected_filename = self.FILEPATH + "storage/myfile"
+
+        with open(expected_filename) as f:
+            self.assertEqual("mydata", f.read())