commit 52194743d5e9e33cbdc3aaa617c4165eeb41ead1
Author: Vangelis Koukis <vkoukis@cslab.ece.ntua.gr>
Date:   Tue Feb 22 13:57:41 2011 +0200

    Update fixtures, introduce created/updated fields.
    
    Introduce auto-generated created/updated fields in all models,
    use two different fixtures, one for db initialization, one for testing.
     * All models have created/updated fields.
     * VirtualMachine model has an owner field.
     * db_test_data.json specified inexistent "max_violations", "quota" fields
       (removed temporarily)
    
    Some tests break.

diff --git a/db/fixtures/db_test_data.json b/db/fixtures/db_test_data.json
new file mode 100644
index 0000000..4fd427f
--- /dev/null
+++ b/db/fixtures/db_test_data.json
@@ -0,0 +1,148 @@
+[
+    {
+        "model": "db.SynnefoUser",
+        "pk": 1,
+        "fields": {
+            "name": "admin user",
+            "created": "2011-02-06 00:00:00",
+            "updated": "2011-02-06 00:00:00",
+            "credit": 1,
+            "monthly_rate": 1,
+            "user" : 1,
+            "violations" : 0
+   	    }
+    },
+    {
+        "model": "db.Flavor",
+        "pk": 1,
+        "fields": {
+            "cpu": 1,
+            "ram": 1024,
+            "disk": 10
+        }
+    },
+    {
+        "model": "db.Flavor",
+        "pk": 2,
+        "fields": {
+            "cpu": 1,
+            "ram": 1024,
+            "disk": 10
+        }
+    },
+    {
+        "model": "db.VirtualMachine",
+        "pk": 1001,
+        "fields": {
+            "name": "snf-1001",
+            "created": "2011-02-06 00:00:00",
+            "updated": "2011-02-06 00:00:00",
+            "charged": "2011-02-06 00:00:00",
+            "sourceimage": 1,
+            "hostid": "HAL-9000",
+            "description": "database server",
+            "ipfour": "192.168.2.1",
+            "ipsix": "::1",
+            "flavor": 1,
+            "_operstate": "STOPPED"
+        }
+    },
+    {
+        "model": "db.VirtualMachine",
+        "pk": 1002,
+        "fields": {
+            "name": "snf-1002",
+            "created": "2011-02-10 00:00:00",
+            "updated": "2011-02-10 00:00:00",
+            "charged": "2011-02-10 00:00:00",
+            "sourceimage": 1,
+            "hostid": "HAL-9000",
+            "description": "mail server",
+            "ipfour": "192.168.2.2",
+            "ipsix": "::2",
+            "flavor": 1,
+            "_operstate": "BUILD"
+        }
+    },
+    {
+        "model": "db.VirtualMachine",
+        "pk": 1003,
+        "fields": {
+            "name": "snf-1003",
+            "created": "2011-02-10 00:00:00",
+            "updated": "2011-02-10 00:00:00",
+            "charged": "2011-02-10 00:00:00",
+            "sourceimage": 1,
+            "hostid": "HAL-9000",
+            "description": "my server",
+            "ipfour": "192.168.2.3",
+            "ipsix": "::3",
+            "flavor": 1,
+            "_operstate": "STARTED"
+        }
+    },
+    {
+        "model": "db.VirtualMachine",
+        "pk": 1004,
+        "fields": {
+            "name": "snf-1004",
+            "created": "2011-02-10 00:00:00",
+            "updated": "2011-02-10 00:00:00",
+            "charged": "2011-02-10 00:00:00",
+            "sourceimage": 1,
+            "hostid": "HAL-9000",
+            "description": "my 2nd server",
+            "ipfour": "192.168.2.4",
+            "ipsix": "::4",
+            "flavor": 1,
+            "_operstate": "STARTED"
+        }
+    },
+    {
+        "model": "db.Image",
+        "pk": 1,
+        "fields": {
+            "name": "Debian Squeeze",
+            "created": "2011-02-06 00:00:00",
+            "updated": "2011-02-06 00:00:00",
+            "state": "ACTIVE",
+            "description": "Full Debian Squeeze Installation"
+        }
+    },
+    {
+        "model": "db.Image",
+        "pk": 2,
+        "fields": {
+            "name": "Slackware 13.1",
+            "created": "2011-02-10 00:00:00",
+            "updated": "2011-02-10 00:00:00",
+            "state": "ACTIVE",
+            "description": "Full Slackware 13.1 Installation",
+            "owner" : 1
+        }
+    },   
+    {
+        "model": "db.Disk",
+        "pk": 1,
+        "fields": {
+            "name": "My_Music",
+            "created": "2011-02-10 00:00:00",
+            "updated": "2011-02-10 00:00:00",
+            "size" : "20",
+            "vm" : "1001",
+            "owner" : "1"
+        }
+    }, 
+    {
+        "model": "db.Disk",
+        "pk": 2,
+        "fields": {
+            "name": "My_Videos",
+            "created": "2011-02-10 00:00:00",
+            "updated": "2011-02-10 00:00:00",
+            "size" : "300",
+            "vm" : "1001",
+            "owner" : "1"
+        }
+    } 
+] 
diff --git a/db/fixtures/initial_data.json b/db/fixtures/initial_data.json
index 027a439..4fd427f 100644
--- a/db/fixtures/initial_data.json
+++ b/db/fixtures/initial_data.json
@@ -4,24 +4,15 @@
         "pk": 1,
         "fields": {
             "name": "admin user",
-            "credit": 0,
-            "created": "2011-02-06",
-            "monthly_rate": 10,
+            "created": "2011-02-06 00:00:00",
+            "updated": "2011-02-06 00:00:00",
+            "credit": 1,
+            "monthly_rate": 1,
             "user" : 1,
             "violations" : 0
    	    }
     },
     {
-        "model" : "db.Limit",
-        "pk" : 1,
-        "fields" : {
-            "name" : "QUOTA_CREDIT",
-            "user" : 1,
-            "value" : 100
-        }
-    }
-    ,
-    {
         "model": "db.Flavor",
         "pk": 1,
         "fields": {
@@ -40,31 +31,12 @@
         }
     },
     {
-        "model" : "db.FlavorCostHistory",
-        "pk" : 1,
-        "fields" : {
-            "cost_active" : 10,
-            "cost_inactive" : 5,
-            "effective_from" : "2011-01-01",
-            "flavor" : 1
-        }
-    },
-    {
-        "model" : "db.FlavorCostHistory",
-        "pk" : 2,
-        "fields" : {
-            "cost_active" : 2,
-            "cost_inactive" : 1,
-            "effective_from" : "2010-01-01",
-            "flavor" : 1
-        }
-    },
-    {
         "model": "db.VirtualMachine",
         "pk": 1001,
         "fields": {
             "name": "snf-1001",
             "created": "2011-02-06 00:00:00",
+            "updated": "2011-02-06 00:00:00",
             "charged": "2011-02-06 00:00:00",
             "sourceimage": 1,
             "hostid": "HAL-9000",
@@ -81,6 +53,7 @@
         "fields": {
             "name": "snf-1002",
             "created": "2011-02-10 00:00:00",
+            "updated": "2011-02-10 00:00:00",
             "charged": "2011-02-10 00:00:00",
             "sourceimage": 1,
             "hostid": "HAL-9000",
@@ -96,8 +69,9 @@
         "pk": 1003,
         "fields": {
             "name": "snf-1003",
-            "created": "2009-02-10 00:00:00",
-            "charged": "2010-01-01 00:00:00",
+            "created": "2011-02-10 00:00:00",
+            "updated": "2011-02-10 00:00:00",
+            "charged": "2011-02-10 00:00:00",
             "sourceimage": 1,
             "hostid": "HAL-9000",
             "description": "my server",
@@ -113,6 +87,7 @@
         "fields": {
             "name": "snf-1004",
             "created": "2011-02-10 00:00:00",
+            "updated": "2011-02-10 00:00:00",
             "charged": "2011-02-10 00:00:00",
             "sourceimage": 1,
             "hostid": "HAL-9000",
@@ -124,57 +99,12 @@
         }
     },
     {
-        "model" : "db.AccountingLog",
-        "pk" : 1,
-        "fields" : {
-            "vm" : 1001,
-            "date" : "2010-01-01",
-            "state" : "STARTED"
-        }
-    },
-    {
-        "model" : "db.AccountingLog",
-        "pk" : 2,
-        "fields" : {
-            "vm" : 1001,
-            "date" : "2011-02-01",
-            "state" : "STARTED"
-        }
-    },
-    {
-        "model" : "db.AccountingLog",
-        "pk" : 3,
-        "fields" : {
-            "vm" : 1003,
-            "date" : "2010-01-01",
-            "state" : "STARTED"
-        }
-    },
-    {
-        "model" : "db.AccountingLog",
-        "pk" : 4,
-        "fields" : {
-            "vm" : 1003,
-            "date" : "2010-03-01",
-            "state" : "STOPPED"
-        }
-    },
-    {
-        "model" : "db.AccountingLog",
-        "pk" : 5,
-        "fields" : {
-            "vm" : 1003,
-            "date" : "2011-01-01",
-            "state" : "STARTED"
-        }
-    },
-    {
         "model": "db.Image",
         "pk": 1,
         "fields": {
             "name": "Debian Squeeze",
-            "updated": "2011-02-06 00:00:00",
             "created": "2011-02-06 00:00:00",
+            "updated": "2011-02-06 00:00:00",
             "state": "ACTIVE",
             "description": "Full Debian Squeeze Installation"
         }
@@ -184,8 +114,8 @@
         "pk": 2,
         "fields": {
             "name": "Slackware 13.1",
-            "updated": "2011-02-10 00:00:00",
             "created": "2011-02-10 00:00:00",
+            "updated": "2011-02-10 00:00:00",
             "state": "ACTIVE",
             "description": "Full Slackware 13.1 Installation",
             "owner" : 1
@@ -197,8 +127,9 @@
         "fields": {
             "name": "My_Music",
             "created": "2011-02-10 00:00:00",
+            "updated": "2011-02-10 00:00:00",
             "size" : "20",
-            "vm" : 1001,
+            "vm" : "1001",
             "owner" : "1"
         }
     }, 
@@ -208,9 +139,10 @@
         "fields": {
             "name": "My_Videos",
             "created": "2011-02-10 00:00:00",
+            "updated": "2011-02-10 00:00:00",
             "size" : "300",
-            "vm" : 1001,
+            "vm" : "1001",
             "owner" : "1"
         }
     } 
-]
\ No newline at end of file
+] 
diff --git a/db/models.py b/db/models.py
index 212f916..802d9de 100644
--- a/db/models.py
+++ b/db/models.py
@@ -12,7 +12,8 @@ backend_prefix_id = settings.BACKEND_PREFIX_ID
 class SynnefoUser(models.Model):
     name = models.CharField(max_length=255)
     credit = models.IntegerField()
-    created = models.DateField()
+    created = models.DateTimeField('Time of creation', auto_now_add=True)
+    updated = models.DateTimeField('Time of last update', auto_now=True)
     monthly_rate = models.IntegerField()
     user = models.ForeignKey(User)
     violations = models.IntegerField()
@@ -73,14 +74,11 @@ class Image(models.Model):
     )
 
     name = models.CharField(max_length=255, help_text=_('description'))
-    updated = models.DateTimeField(help_text=_("Image update date"))
-    created = models.DateTimeField(help_text=_("Image creation date"), default=datetime.datetime.now())
     state = models.CharField(choices=IMAGE_STATES, max_length=30)
     description = models.TextField(help_text=_('description'))
     owner = models.ForeignKey(SynnefoUser,blank=True, null=True)
-    #FIXME: ImageMetadata, as in VirtualMachineMetadata
-    #       "os" contained in metadata. Newly created Server inherits value of "os" metadata key from Image.
-    #       The Web UI uses the value of "os" to determine the icon to use.
+    created = models.DateTimeField('Time of creation', auto_now_add=True)
+    updated = models.DateTimeField('Time of last update', auto_now=True)
 
     class Meta:
         verbose_name = u'Image'
@@ -258,8 +256,10 @@ class VirtualMachine(models.Model):
     }
 
     name = models.CharField(max_length=255)
-    created = models.DateTimeField(help_text=_('VM creation date'), default=datetime.datetime.now())
-    charged = models.DateTimeField()
+    owner = models.ForeignKey(SynnefoUser,blank=True, null=True)
+    created = models.DateTimeField('Time of creation', auto_now_add=True)
+    updated = models.DateTimeField('Time of last update', auto_now=True)
+    charged = models.DateTimeField('Time of last charge', default=datetime.datetime.now())
     # Use string reference to avoid circular ForeignKey def.
     # FIXME: "sourceimage" works, "image" causes validation errors. See "related_name" in the Django docs.
     sourceimage = models.ForeignKey(Image, null=False) 
@@ -270,8 +270,14 @@ class VirtualMachine(models.Model):
     flavor = models.ForeignKey(Flavor)
     suspended = models.BooleanField('Administratively Suspended')
 
-    # VM State [volatile data]
-    updated = models.DateTimeField(null=True)
+    # VM State 
+    # The following fields are volatile data, in the sense
+    # that they need not be persistent in the DB, but rather
+    # get generated at runtime by quering Ganeti and applying
+    # updates received from Ganeti.
+    #
+    # They belong to a separate caching layer, in the long run.
+    # [vkoukis] after discussion with [faidon].
     action = models.CharField(choices=ACTIONS, max_length=30, null=True)
     _operstate = models.CharField(choices=OPER_STATES, max_length=30, null=True)
     _backendjobid = models.PositiveIntegerField(null=True)
@@ -320,7 +326,6 @@ class VirtualMachine(models.Model):
         if not self.pk: 
             self._action = None
             self._operstate = "BUILD"
-            self.updated = datetime.datetime.now()
             self._backendjobid = None
             self._backendjobstatus = None
             self._backendopcode = None
@@ -351,8 +356,6 @@ class VirtualMachine(models.Model):
             self._operstate = 'ERROR'
         # Any other notification of failure leaves the operating state unchanged
 
-        # FIXME: Should be implemented in a pre-save signal handler.
-        self.updated = datetime.datetime.now()
         self.save()
 
     def start_action(self, action):
@@ -364,7 +367,7 @@ class VirtualMachine(models.Model):
         self._backendjobid = None
         self._backendopcode = None
         self._backendlogmsg = None
-        self.updated = datetime.datetime.now()
+        
         self.save()
 
     # FIXME: Perhaps move somewhere else, outside the model?
@@ -399,11 +402,12 @@ class VirtualMachine(models.Model):
 
 
 class VirtualMachineGroup(models.Model):
-    "Groups of VM's for SynnefoUsers"
+    """Groups of VMs for SynnefoUsers"""
     name = models.CharField(max_length=255)
+    created = models.DateTimeField('Time of creation', auto_now_add=True)
+    updated = models.DateTimeField('Time of last update', auto_now=True)
     owner = models.ForeignKey(SynnefoUser)
     machines = models.ManyToManyField(VirtualMachine)
-    created = models.DateTimeField(help_text=_("Group creation date"), default=datetime.datetime.now())
 
     class Meta:
         verbose_name = u'Virtual Machine Group'
@@ -447,11 +451,12 @@ class AccountingLog(models.Model):
 
 class Disk(models.Model):
     name = models.CharField(max_length=255)
-    created = models.DateTimeField('Disk creation date', default=datetime.datetime.now())
+    created = models.DateTimeField('Time of creation', auto_now_add=True)
+    updated = models.DateTimeField('Time of last update', auto_now=True)
     size = models.PositiveIntegerField('Disk size in GBs')
     vm = models.ForeignKey(VirtualMachine, blank=True, null=True)
     owner = models.ForeignKey(SynnefoUser, blank=True, null=True)  
-    
+
     class Meta:
         verbose_name = u'Disk instance'
 
