diff --git a/app/settings.py b/app/settings.py index f966f70..1f71d8d 100644 --- a/app/settings.py +++ b/app/settings.py @@ -162,6 +162,8 @@ NGNIX_DEFAULT_REDIRECT = '' +BACKUP_SET_LOCK = '/tmp/_azimutgestion_backuplock.lock' + try: from settingsLocal import * except ImportError: diff --git a/app/utils.py b/app/utils.py new file mode 100644 index 0000000..c670764 --- /dev/null +++ b/app/utils.py @@ -0,0 +1,20 @@ +class DjangoLock: + + def __init__(self, filename): + self.filename = filename + # This will create it if it does not exist already + self.handle = open(filename, 'w') + + # flock() is a blocking call unless it is bitwise ORed with LOCK_NB to avoid blocking + # on lock acquisition. This blocking is what I use to provide atomicity across forked + # Django processes since native python locks and semaphores only work at the thread level + def acquire(self): + import fcntl + fcntl.flock(self.handle, fcntl.LOCK_EX) + + def release(self): + import fcntl + fcntl.flock(self.handle, fcntl.LOCK_UN) + + def __del__(self): + self.handle.close() diff --git a/backups/migrations/0006_auto__add_backupsetofrun.py b/backups/migrations/0006_auto__add_backupsetofrun.py new file mode 100644 index 0000000..d25b6ba --- /dev/null +++ b/backups/migrations/0006_auto__add_backupsetofrun.py @@ -0,0 +1,138 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding model 'BackupSetOfRun' + db.create_table(u'backups_backupsetofrun', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('type', self.gf('django.db.models.fields.CharField')(max_length=16)), + ('status', self.gf('django.db.models.fields.CharField')(max_length=16)), + ('start_date', self.gf('django.db.models.fields.DateTimeField')()), + ('end_date', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)), + ('total_size', self.gf('django.db.models.fields.BigIntegerField')()), + ('total_files', self.gf('django.db.models.fields.BigIntegerField')()), + )) + db.send_create_signal(u'backups', ['BackupSetOfRun']) + + # Adding M2M table for field backups on 'BackupSetOfRun' + m2m_table_name = db.shorten_name(u'backups_backupsetofrun_backups') + db.create_table(m2m_table_name, ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('backupsetofrun', models.ForeignKey(orm[u'backups.backupsetofrun'], null=False)), + ('backuprun', models.ForeignKey(orm[u'backups.backuprun'], null=False)) + )) + db.create_unique(m2m_table_name, ['backupsetofrun_id', 'backuprun_id']) + + + def backwards(self, orm): + # Deleting model 'BackupSetOfRun' + db.delete_table(u'backups_backupsetofrun') + + # Removing M2M table for field backups on 'BackupSetOfRun' + db.delete_table(db.shorten_name(u'backups_backupsetofrun_backups')) + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'backups.backup': { + 'Meta': {'object_name': 'Backup'}, + 'active': ('django.db.models.fields.BooleanField', [], {}), + 'excludes': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'folder_from': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'folder_to': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'prox_and_sys_excludes': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'server_from': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'backups_of_the_server'", 'to': u"orm['servers.Server']"}), + 'server_to': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'backups_on_the_server'", 'to': u"orm['servers.Server']"}) + }, + u'backups.backuprun': { + 'Meta': {'object_name': 'BackupRun'}, + 'backup': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['backups.Backup']"}), + 'end_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'nb_files': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}), + 'size': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}), + 'start_date': ('django.db.models.fields.DateTimeField', [], {}), + 'stderr': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'stdout': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + u'backups.backupsetofrun': { + 'Meta': {'object_name': 'BackupSetOfRun'}, + 'backups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['backups.BackupRun']", 'symmetrical': 'False'}), + 'end_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'start_date': ('django.db.models.fields.DateTimeField', [], {}), + 'status': ('django.db.models.fields.CharField', [], {'max_length': '16'}), + 'total_files': ('django.db.models.fields.BigIntegerField', [], {}), + 'total_size': ('django.db.models.fields.BigIntegerField', [], {}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '16'}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + u'servers.server': { + 'Meta': {'object_name': 'Server'}, + 'external_hostname_for_vms_creation': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'external_interface': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'external_ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'hostname_for_vms_creation': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'internal_ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'is_proxmox': ('django.db.models.fields.BooleanField', [], {}), + 'is_vm': ('django.db.models.fields.BooleanField', [], {}), + 'keymanger_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'logstash_shipper': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'mysql_server': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'mysqled_server_set'", 'null': 'True', 'to': u"orm['servers.Server']"}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'ngnix_server': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'ngnixed_server_set'", 'null': 'True', 'to': u"orm['servers.Server']"}), + 'notes': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'proxmox_node_name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'samba_base_folder': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'samba_management': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'ssh_connection_string_from_backup': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'ssh_connection_string_from_gestion': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'users_owning_the_server': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}), + 'vm_host': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'server_set'", 'null': 'True', 'to': u"orm['servers.Server']"}) + } + } + + complete_apps = ['backups'] \ No newline at end of file diff --git a/backups/migrations/0007_auto.py b/backups/migrations/0007_auto.py new file mode 100644 index 0000000..735680e --- /dev/null +++ b/backups/migrations/0007_auto.py @@ -0,0 +1,124 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding M2M table for field backupruns on 'BackupSetOfRun' + m2m_table_name = db.shorten_name(u'backups_backupsetofrun_backupruns') + db.create_table(m2m_table_name, ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('backupsetofrun', models.ForeignKey(orm[u'backups.backupsetofrun'], null=False)), + ('backuprun', models.ForeignKey(orm[u'backups.backuprun'], null=False)) + )) + db.create_unique(m2m_table_name, ['backupsetofrun_id', 'backuprun_id']) + + + def backwards(self, orm): + # Removing M2M table for field backupruns on 'BackupSetOfRun' + db.delete_table(db.shorten_name(u'backups_backupsetofrun_backupruns')) + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'backups.backup': { + 'Meta': {'object_name': 'Backup'}, + 'active': ('django.db.models.fields.BooleanField', [], {}), + 'excludes': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'folder_from': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'folder_to': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'prox_and_sys_excludes': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'server_from': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'backups_of_the_server'", 'to': u"orm['servers.Server']"}), + 'server_to': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'backups_on_the_server'", 'to': u"orm['servers.Server']"}) + }, + u'backups.backuprun': { + 'Meta': {'object_name': 'BackupRun'}, + 'backup': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['backups.Backup']"}), + 'end_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'nb_files': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}), + 'size': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}), + 'start_date': ('django.db.models.fields.DateTimeField', [], {}), + 'stderr': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'stdout': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + u'backups.backupsetofrun': { + 'Meta': {'object_name': 'BackupSetOfRun'}, + 'backupruns': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['backups.BackupRun']", 'symmetrical': 'False'}), + 'backups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['backups.Backup']", 'symmetrical': 'False'}), + 'end_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'start_date': ('django.db.models.fields.DateTimeField', [], {}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'running'", 'max_length': '16'}), + 'total_files': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}), + 'total_size': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '16'}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + u'servers.server': { + 'Meta': {'object_name': 'Server'}, + 'external_hostname_for_vms_creation': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'external_interface': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'external_ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'hostname_for_vms_creation': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'internal_ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'is_proxmox': ('django.db.models.fields.BooleanField', [], {}), + 'is_vm': ('django.db.models.fields.BooleanField', [], {}), + 'keymanger_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'logstash_shipper': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'mysql_server': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'mysqled_server_set'", 'null': 'True', 'to': u"orm['servers.Server']"}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'ngnix_server': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'ngnixed_server_set'", 'null': 'True', 'to': u"orm['servers.Server']"}), + 'notes': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'proxmox_node_name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'samba_base_folder': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'samba_management': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'ssh_connection_string_from_backup': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'ssh_connection_string_from_gestion': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'users_owning_the_server': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}), + 'vm_host': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'server_set'", 'null': 'True', 'to': u"orm['servers.Server']"}) + } + } + + complete_apps = ['backups'] \ No newline at end of file diff --git a/backups/migrations/0008_auto__chg_field_backupsetofrun_start_date.py b/backups/migrations/0008_auto__chg_field_backupsetofrun_start_date.py new file mode 100644 index 0000000..4f41dcf --- /dev/null +++ b/backups/migrations/0008_auto__chg_field_backupsetofrun_start_date.py @@ -0,0 +1,118 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + + # Changing field 'BackupSetOfRun.start_date' + db.alter_column(u'backups_backupsetofrun', 'start_date', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True)) + + def backwards(self, orm): + + # Changing field 'BackupSetOfRun.start_date' + db.alter_column(u'backups_backupsetofrun', 'start_date', self.gf('django.db.models.fields.DateTimeField')()) + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'backups.backup': { + 'Meta': {'object_name': 'Backup'}, + 'active': ('django.db.models.fields.BooleanField', [], {}), + 'excludes': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'folder_from': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'folder_to': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'prox_and_sys_excludes': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'server_from': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'backups_of_the_server'", 'to': u"orm['servers.Server']"}), + 'server_to': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'backups_on_the_server'", 'to': u"orm['servers.Server']"}) + }, + u'backups.backuprun': { + 'Meta': {'object_name': 'BackupRun'}, + 'backup': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['backups.Backup']"}), + 'end_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'nb_files': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}), + 'size': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}), + 'start_date': ('django.db.models.fields.DateTimeField', [], {}), + 'stderr': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'stdout': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + u'backups.backupsetofrun': { + 'Meta': {'object_name': 'BackupSetOfRun'}, + 'backupruns': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['backups.BackupRun']", 'symmetrical': 'False'}), + 'backups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['backups.Backup']", 'symmetrical': 'False'}), + 'end_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'start_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'running'", 'max_length': '16'}), + 'total_files': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}), + 'total_size': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '16'}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + u'servers.server': { + 'Meta': {'object_name': 'Server'}, + 'external_hostname_for_vms_creation': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'external_interface': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'external_ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'hostname_for_vms_creation': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'internal_ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'is_proxmox': ('django.db.models.fields.BooleanField', [], {}), + 'is_vm': ('django.db.models.fields.BooleanField', [], {}), + 'keymanger_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'logstash_shipper': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'mysql_server': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'mysqled_server_set'", 'null': 'True', 'to': u"orm['servers.Server']"}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'ngnix_server': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'ngnixed_server_set'", 'null': 'True', 'to': u"orm['servers.Server']"}), + 'notes': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'proxmox_node_name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'samba_base_folder': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'samba_management': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'ssh_connection_string_from_backup': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'ssh_connection_string_from_gestion': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'users_owning_the_server': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}), + 'vm_host': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'server_set'", 'null': 'True', 'to': u"orm['servers.Server']"}) + } + } + + complete_apps = ['backups'] \ No newline at end of file diff --git a/backups/migrations/0009_auto.py b/backups/migrations/0009_auto.py new file mode 100644 index 0000000..5923abc --- /dev/null +++ b/backups/migrations/0009_auto.py @@ -0,0 +1,134 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Removing M2M table for field backups on 'BackupSetOfRun' + db.delete_table(db.shorten_name(u'backups_backupsetofrun_backups')) + + # Removing M2M table for field backupruns on 'BackupSetOfRun' + db.delete_table(db.shorten_name(u'backups_backupsetofrun_backupruns')) + + + def backwards(self, orm): + # Adding M2M table for field backups on 'BackupSetOfRun' + m2m_table_name = db.shorten_name(u'backups_backupsetofrun_backups') + db.create_table(m2m_table_name, ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('backupsetofrun', models.ForeignKey(orm[u'backups.backupsetofrun'], null=False)), + ('backup', models.ForeignKey(orm[u'backups.backup'], null=False)) + )) + db.create_unique(m2m_table_name, ['backupsetofrun_id', 'backup_id']) + + # Adding M2M table for field backupruns on 'BackupSetOfRun' + m2m_table_name = db.shorten_name(u'backups_backupsetofrun_backupruns') + db.create_table(m2m_table_name, ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('backupsetofrun', models.ForeignKey(orm[u'backups.backupsetofrun'], null=False)), + ('backuprun', models.ForeignKey(orm[u'backups.backuprun'], null=False)) + )) + db.create_unique(m2m_table_name, ['backupsetofrun_id', 'backuprun_id']) + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'backups.backup': { + 'Meta': {'object_name': 'Backup'}, + 'active': ('django.db.models.fields.BooleanField', [], {}), + 'excludes': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'folder_from': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'folder_to': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'prox_and_sys_excludes': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'server_from': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'backups_of_the_server'", 'to': u"orm['servers.Server']"}), + 'server_to': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'backups_on_the_server'", 'to': u"orm['servers.Server']"}) + }, + u'backups.backuprun': { + 'Meta': {'object_name': 'BackupRun'}, + 'backup': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['backups.Backup']"}), + 'end_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'nb_files': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}), + 'size': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}), + 'start_date': ('django.db.models.fields.DateTimeField', [], {}), + 'stderr': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'stdout': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + u'backups.backupsetofrun': { + 'Meta': {'object_name': 'BackupSetOfRun'}, + 'end_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'start_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'running'", 'max_length': '16'}), + 'total_files': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}), + 'total_size': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '16'}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + u'servers.server': { + 'Meta': {'object_name': 'Server'}, + 'external_hostname_for_vms_creation': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'external_interface': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'external_ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'hostname_for_vms_creation': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'internal_ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'is_proxmox': ('django.db.models.fields.BooleanField', [], {}), + 'is_vm': ('django.db.models.fields.BooleanField', [], {}), + 'keymanger_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'logstash_shipper': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'mysql_server': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'mysqled_server_set'", 'null': 'True', 'to': u"orm['servers.Server']"}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'ngnix_server': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'ngnixed_server_set'", 'null': 'True', 'to': u"orm['servers.Server']"}), + 'notes': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'proxmox_node_name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'samba_base_folder': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'samba_management': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'ssh_connection_string_from_backup': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'ssh_connection_string_from_gestion': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'users_owning_the_server': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}), + 'vm_host': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'server_set'", 'null': 'True', 'to': u"orm['servers.Server']"}) + } + } + + complete_apps = ['backups'] \ No newline at end of file diff --git a/backups/migrations/0010_auto.py b/backups/migrations/0010_auto.py new file mode 100644 index 0000000..8f50fd7 --- /dev/null +++ b/backups/migrations/0010_auto.py @@ -0,0 +1,136 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding M2M table for field backupruns on 'BackupSetOfRun' + m2m_table_name = db.shorten_name(u'backups_backupsetofrun_backupruns') + db.create_table(m2m_table_name, ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('backupsetofrun', models.ForeignKey(orm[u'backups.backupsetofrun'], null=False)), + ('backuprun', models.ForeignKey(orm[u'backups.backuprun'], null=False)) + )) + db.create_unique(m2m_table_name, ['backupsetofrun_id', 'backuprun_id']) + + # Adding M2M table for field backups on 'BackupSetOfRun' + m2m_table_name = db.shorten_name(u'backups_backupsetofrun_backups') + db.create_table(m2m_table_name, ( + ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)), + ('backupsetofrun', models.ForeignKey(orm[u'backups.backupsetofrun'], null=False)), + ('backup', models.ForeignKey(orm[u'backups.backup'], null=False)) + )) + db.create_unique(m2m_table_name, ['backupsetofrun_id', 'backup_id']) + + + def backwards(self, orm): + # Removing M2M table for field backupruns on 'BackupSetOfRun' + db.delete_table(db.shorten_name(u'backups_backupsetofrun_backupruns')) + + # Removing M2M table for field backups on 'BackupSetOfRun' + db.delete_table(db.shorten_name(u'backups_backupsetofrun_backups')) + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'backups.backup': { + 'Meta': {'object_name': 'Backup'}, + 'active': ('django.db.models.fields.BooleanField', [], {}), + 'excludes': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'folder_from': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'folder_to': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'prox_and_sys_excludes': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'server_from': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'backups_of_the_server'", 'to': u"orm['servers.Server']"}), + 'server_to': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'backups_on_the_server'", 'to': u"orm['servers.Server']"}) + }, + u'backups.backuprun': { + 'Meta': {'object_name': 'BackupRun'}, + 'backup': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['backups.Backup']"}), + 'end_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'nb_files': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}), + 'size': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}), + 'start_date': ('django.db.models.fields.DateTimeField', [], {}), + 'stderr': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'stdout': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + u'backups.backupsetofrun': { + 'Meta': {'object_name': 'BackupSetOfRun'}, + 'backupruns': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['backups.BackupRun']", 'symmetrical': 'False'}), + 'backups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['backups.Backup']", 'symmetrical': 'False'}), + 'end_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'start_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'running'", 'max_length': '16'}), + 'total_files': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}), + 'total_size': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '16'}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + u'servers.server': { + 'Meta': {'object_name': 'Server'}, + 'external_hostname_for_vms_creation': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'external_interface': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'external_ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'hostname_for_vms_creation': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'internal_ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'is_proxmox': ('django.db.models.fields.BooleanField', [], {}), + 'is_vm': ('django.db.models.fields.BooleanField', [], {}), + 'keymanger_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'logstash_shipper': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'mysql_server': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'mysqled_server_set'", 'null': 'True', 'to': u"orm['servers.Server']"}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'ngnix_server': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'ngnixed_server_set'", 'null': 'True', 'to': u"orm['servers.Server']"}), + 'notes': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'proxmox_node_name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'samba_base_folder': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'samba_management': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'ssh_connection_string_from_backup': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'ssh_connection_string_from_gestion': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'users_owning_the_server': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}), + 'vm_host': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'server_set'", 'null': 'True', 'to': u"orm['servers.Server']"}) + } + } + + complete_apps = ['backups'] \ No newline at end of file diff --git a/backups/migrations/0011_auto__add_backupnotification__add_backupuserwhowantnotifs.py b/backups/migrations/0011_auto__add_backupnotification__add_backupuserwhowantnotifs.py new file mode 100644 index 0000000..341be33 --- /dev/null +++ b/backups/migrations/0011_auto__add_backupnotification__add_backupuserwhowantnotifs.py @@ -0,0 +1,148 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding model 'BackupNotification' + db.create_table(u'backups_backupnotification', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('when', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), + ('type', self.gf('django.db.models.fields.CharField')(max_length=32)), + ('message', self.gf('django.db.models.fields.TextField')()), + )) + db.send_create_signal(u'backups', ['BackupNotification']) + + # Adding model 'BackupUserWhoWantNotifs' + db.create_table(u'backups_backupuserwhowantnotifs', ( + (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('type', self.gf('django.db.models.fields.CharField')(max_length=32)), + ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])), + )) + db.send_create_signal(u'backups', ['BackupUserWhoWantNotifs']) + + + def backwards(self, orm): + # Deleting model 'BackupNotification' + db.delete_table(u'backups_backupnotification') + + # Deleting model 'BackupUserWhoWantNotifs' + db.delete_table(u'backups_backupuserwhowantnotifs') + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'backups.backup': { + 'Meta': {'object_name': 'Backup'}, + 'active': ('django.db.models.fields.BooleanField', [], {}), + 'excludes': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'folder_from': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'folder_to': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'prox_and_sys_excludes': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'server_from': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'backups_of_the_server'", 'to': u"orm['servers.Server']"}), + 'server_to': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'backups_on_the_server'", 'to': u"orm['servers.Server']"}) + }, + u'backups.backupnotification': { + 'Meta': {'object_name': 'BackupNotification'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'message': ('django.db.models.fields.TextField', [], {}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'when': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}) + }, + u'backups.backuprun': { + 'Meta': {'object_name': 'BackupRun'}, + 'backup': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['backups.Backup']"}), + 'end_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'nb_files': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}), + 'size': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}), + 'start_date': ('django.db.models.fields.DateTimeField', [], {}), + 'stderr': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'stdout': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + u'backups.backupsetofrun': { + 'Meta': {'object_name': 'BackupSetOfRun'}, + 'backupruns': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['backups.BackupRun']", 'symmetrical': 'False'}), + 'backups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['backups.Backup']", 'symmetrical': 'False'}), + 'end_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'start_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'running'", 'max_length': '16'}), + 'total_files': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}), + 'total_size': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '16'}) + }, + u'backups.backupuserwhowantnotifs': { + 'Meta': {'object_name': 'BackupUserWhoWantNotifs'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + u'servers.server': { + 'Meta': {'object_name': 'Server'}, + 'external_hostname_for_vms_creation': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'external_interface': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'external_ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'hostname_for_vms_creation': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'internal_ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'is_proxmox': ('django.db.models.fields.BooleanField', [], {}), + 'is_vm': ('django.db.models.fields.BooleanField', [], {}), + 'keymanger_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'logstash_shipper': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'mysql_server': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'mysqled_server_set'", 'null': 'True', 'to': u"orm['servers.Server']"}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'ngnix_server': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'ngnixed_server_set'", 'null': 'True', 'to': u"orm['servers.Server']"}), + 'notes': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'proxmox_node_name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'samba_base_folder': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'samba_management': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'ssh_connection_string_from_backup': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'ssh_connection_string_from_gestion': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'users_owning_the_server': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}), + 'vm_host': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'server_set'", 'null': 'True', 'to': u"orm['servers.Server']"}) + } + } + + complete_apps = ['backups'] \ No newline at end of file diff --git a/backups/migrations/0012_auto__add_field_backuprun_type.py b/backups/migrations/0012_auto__add_field_backuprun_type.py new file mode 100644 index 0000000..33eb5e3 --- /dev/null +++ b/backups/migrations/0012_auto__add_field_backuprun_type.py @@ -0,0 +1,134 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding field 'BackupRun.type' + db.add_column(u'backups_backuprun', 'type', + self.gf('django.db.models.fields.CharField')(default='hourly', max_length=16), + keep_default=False) + + + def backwards(self, orm): + # Deleting field 'BackupRun.type' + db.delete_column(u'backups_backuprun', 'type') + + + models = { + u'auth.group': { + 'Meta': {'object_name': 'Group'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + u'auth.permission': { + 'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + u'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + u'backups.backup': { + 'Meta': {'object_name': 'Backup'}, + 'active': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'excludes': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'folder_from': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'folder_to': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'prox_and_sys_excludes': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'server_from': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'backups_of_the_server'", 'to': u"orm['servers.Server']"}), + 'server_to': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'backups_on_the_server'", 'to': u"orm['servers.Server']"}) + }, + u'backups.backupnotification': { + 'Meta': {'object_name': 'BackupNotification'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'message': ('django.db.models.fields.TextField', [], {}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'when': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}) + }, + u'backups.backuprun': { + 'Meta': {'object_name': 'BackupRun'}, + 'backup': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['backups.Backup']"}), + 'end_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'nb_files': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}), + 'size': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}), + 'start_date': ('django.db.models.fields.DateTimeField', [], {}), + 'stderr': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'stdout': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '16'}) + }, + u'backups.backupsetofrun': { + 'Meta': {'object_name': 'BackupSetOfRun'}, + 'backupruns': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['backups.BackupRun']", 'symmetrical': 'False'}), + 'backups': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['backups.Backup']", 'symmetrical': 'False'}), + 'end_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'start_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'running'", 'max_length': '16'}), + 'total_files': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}), + 'total_size': ('django.db.models.fields.BigIntegerField', [], {'default': '0'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '16'}) + }, + u'backups.backupuserwhowantnotifs': { + 'Meta': {'object_name': 'BackupUserWhoWantNotifs'}, + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}) + }, + u'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + u'servers.server': { + 'Meta': {'object_name': 'Server'}, + 'external_hostname_for_vms_creation': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'external_interface': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'external_ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'hostname_for_vms_creation': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'null': 'True', 'blank': 'True'}), + u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'internal_ip': ('django.db.models.fields.IPAddressField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'is_proxmox': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_vm': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'keymanger_name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}), + 'logstash_shipper': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'mysql_server': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'mysqled_server_set'", 'null': 'True', 'to': u"orm['servers.Server']"}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'ngnix_server': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'ngnixed_server_set'", 'null': 'True', 'to': u"orm['servers.Server']"}), + 'notes': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'proxmox_node_name': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'samba_base_folder': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'samba_management': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'ssh_connection_string_from_backup': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'ssh_connection_string_from_gestion': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'users_owning_the_server': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}), + 'vm_host': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'server_set'", 'null': 'True', 'to': u"orm['servers.Server']"}) + } + } + + complete_apps = ['backups'] \ No newline at end of file diff --git a/backups/models.py b/backups/models.py index 898528a..ff543f0 100644 --- a/backups/models.py +++ b/backups/models.py @@ -1,6 +1,11 @@ from django.db import models from servers.models import Server +from django.utils import timezone + +from django.contrib.auth.models import User + +from django.core.mail import send_mail class Backup(models.Model): @@ -38,7 +43,120 @@ class BackupRun(models.Model): stdout = models.TextField(blank=True, null=True) stderr = models.TextField(blank=True, null=True) + TYPE_CHOICES = ( + ('hourly', 'Hourly'), + ('daily', 'Daily'), + ('weekly', 'Weekly'), + ('monthly', 'Monthly'), + ) + + type = models.CharField(max_length=16, choices=TYPE_CHOICES) + def not_too_old(self): from django.utils import timezone import datetime return (self.end_date + datetime.timedelta(days=3)) > timezone.now() + + +class BackupSetOfRun(models.Model): + + TYPE_CHOICES = ( + ('hourly', 'Hourly'), + ('daily', 'Daily'), + ('weekly', 'Weekly'), + ('monthly', 'Monthly'), + ) + + type = models.CharField(max_length=16, choices=TYPE_CHOICES) + + STATUS_CHOICES = ( + ('running', 'Running'), + ('done', 'Done'), + ('canceled', 'Cancelled'), + ) + + status = models.CharField(max_length=16, choices=STATUS_CHOICES, default='running') + + start_date = models.DateTimeField(auto_now_add=True) + end_date = models.DateTimeField(blank=True, null=True) + + backupruns = models.ManyToManyField(BackupRun) + backups = models.ManyToManyField(Backup) + + total_size = models.BigIntegerField(default=0) + total_files = models.BigIntegerField(default=0) + + def get_status_label(self): + VALUES = {'running': 'warning', 'done': 'success', 'canceled': 'important'} + + if self.status in VALUES: + return VALUES[self.status] + else: + return 'important' + + def get_total_time(self): + if not self.end_date: + end_date = timezone.now() + else: + end_date = self.end_date + + return int((end_date - self.start_date).total_seconds() / 36.0) / 100.0 + + def get_total_time_label(self): + + tt = self.get_total_time() + + if tt < 3.5: + return 'success' + if tt < 4.0: + return 'warning' + return 'important' + + +class BackupNotification(models.Model): + + when = models.DateTimeField(auto_now_add=True) + + TYPE_CHOICES = ( + ('bkpdone', 'Backup completed'), + ('bkpsetdone', 'Set of backup completed'), + ('bkpsetnotstarted', 'Set of backup not started'), + ('bkpsetcanceled', 'Set of backup canceled'), + ('bkpfailled', 'Backup failled'), + ) + + type = models.CharField(max_length=32, choices=TYPE_CHOICES) + + message = models.TextField() + + VALUES = {'bkpdone': 'success', 'bkpsetdone': 'success', 'bkpsetnotstarted': 'important', 'bkpfailled': 'important', 'bkpsetcanceled': 'warning'} + + @staticmethod + def get_types_with_labels(): + retour = [] + + for (key, text) in BackupNotification.TYPE_CHOICES: + retour.append((key, text, BackupNotification.VALUES[key])) + + return retour + + def get_type_label(self): + + if self.type in self.VALUES: + return self.VALUES[self.type] + else: + return 'important' + + def send_notifications(self): + + subject = "Notification from AzimutGestion: %s" % (self.get_type_display(), ) + + recpts = [buwwn.user.email for buwwn in BackupUserWhoWantNotifs.objects.filter(type=self.type).all()] + + send_mail(subject, self.message, 'norepoly@azimut-prod.com', recpts, True) + + +class BackupUserWhoWantNotifs(models.Model): + + type = models.CharField(max_length=32, choices=BackupNotification.TYPE_CHOICES) + user = models.ForeignKey(User) diff --git a/backups/tasks.py b/backups/tasks.py index 78c6f4b..d65c2f0 100644 --- a/backups/tasks.py +++ b/backups/tasks.py @@ -3,39 +3,51 @@ import re from django.utils import timezone -from backups.models import Backup, BackupRun +from backups.models import Backup, BackupRun, BackupSetOfRun, BackupNotification import os from django.conf import settings +from app.utils import DjangoLock + @task(ignore_result=True) -def run_backup(id, mode='hourly'): +def run_backup(id, mode='hourly', backupsetpk=None): """Run a backup""" backup = Backup.objects.get(pk=id) # Create the run - backuprun = BackupRun(backup=backup, start_date=timezone.now()) + backuprun = BackupRun(backup=backup, start_date=timezone.now(), type=mode) backuprun.save() + def _notify_set_if_needed(): + if backupsetpk: + check_end_of_backupset.delay(backupsetpk, backuprun.pk) + # Backup if not backup.server_to.ssh_connection_string_from_gestion: - print "Error: No connection from gestion" + print("Error: No connection from gestion") + _notify_set_if_needed() return if not backup.server_from.ssh_connection_string_from_backup: - print "Error: No connection from backup" + print("Error: No connection from backup") + _notify_set_if_needed() return - os.system('ssh ' + backup.server_to.ssh_connection_string_from_gestion + ' wget ' + settings.GESTION_URL + 'backups/get_conf/' + str(backup.pk) + '/ -O /tmp/azimut-gestion-backup-config-' + str(backup.pk)) - - to_do_string = ['rsnapshot -c /tmp/azimut-gestion-backup-config-' + str(backup.pk) + ' -v ' + mode] - - import subprocess - p = subprocess.Popen(['ssh'] + backup.server_to.ssh_connection_string_from_gestion.split(' ') + [' '.join(to_do_string)], stdout=subprocess.PIPE, stderr=subprocess.PIPE) +# os.system('ssh ' + backup.server_to.ssh_connection_string_from_gestion + ' wget ' + settings.GESTION_URL + 'backups/get_conf/' + str(backup.pk) + '/ -O /tmp/azimut-gestion-backup-config-' + str(backup.pk)) +# +# to_do_string = ['rsnapshot -c /tmp/azimut-gestion-backup-config-' + str(backup.pk) + ' -v ' + mode] +# +# import subprocess +# p = subprocess.Popen(['ssh'] + backup.server_to.ssh_connection_string_from_gestion.split(' ') + [' '.join(to_do_string)], stdout=subprocess.PIPE, stderr=subprocess.PIPE) +# +# out, err = p.communicate() - out, err = p.communicate() + import time + time.sleep(10) + out, err = "1", "2" backuprun.end_date = timezone.now() backuprun.stdout = out @@ -44,20 +56,94 @@ def run_backup(id, mode='hourly'): try: backuprun.nb_files = re.search('Number of files: (\d*)', out).group(1) or 0 except: - print "Error getting nb files" + print("Error getting nb files") pass try: backuprun.size = re.search('Total file size: (\d*)', out).group(1) or 0 except: - print "Error getting total file size" + print("Error getting total file size") pass backuprun.save() + if not backuprun.nb_files or not backuprun.size: + bn = BackupNotification(type='bkpfailled') + bn.message = "The backuprun for the backup %s started at %s, ended at %s, type %s has failled:" % (backuprun.backup.name, str(backuprun.start_date), str(backuprun.end_date), mode,) + else: + bn = BackupNotification(type='bkpfailled') + bn.message = "The backuprun for the backup %s started at %s, ended at %s, type %s was succesfull:" % (backuprun.backup.name, str(backuprun.start_date), str(backuprun.end_date), mode,) + + bn.message += "\n\n%s files where copied for a total size of %s." % (str(backuprun.nb_files), str(backuprun.size),) + bn.save() + bn.send_notifications() + + _notify_set_if_needed() + @task(ignore_result=True) def run_active_backups(mode): """Run all actives backups""" - for bkp in Backup.objects.filter(active=True).all(): - run_backup.delay(bkp.pk, mode) + # If we're in hourly mode, check that the previous backup was done. (In + # othercases, it's ok to run more than one at a time) + if mode == 'hourly': + oldbackupruns = BackupSetOfRun.objects.filter(type='hourly', status='running').all() + + if oldbackupruns: + + bn = BackupNotification(type='bkpsetnotstarted') + bn.message = "The backupset of type %s whould should have been started at %s was not executed. A previous backupset was still running. If it's not the case, you can, after carefully checked what happened, use the interface to manually ignore the set." % (mode, str(timezone.now()),) + + bn.save() + bn.send_notifications() + print("Aborting run as there is still backup runnning !") + return + + backups_to_run = Backup.objects.filter(active=True).all() + + backupset = BackupSetOfRun(type=mode) + backupset.save() + + for bpk in backups_to_run: + backupset.backups.add(bpk) + + backupset.save() + + for bkp in backups_to_run: + run_backup.delay(bkp.pk, mode, backupset.pk) + + +@task(ignore_result=True) +def check_end_of_backupset(backupsetpk, backuprunpk): + + l = DjangoLock(settings.BACKUP_SET_LOCK) + + l.acquire() + + backupset = BackupSetOfRun.objects.get(pk=backupsetpk) + backuprun = BackupRun.objects.get(pk=backuprunpk) + + try: + + backupset.backups.remove(backuprun.backup) + backupset.backupruns.add(backuprun) + + backupset.total_size += backuprun.size + backupset.total_files += backuprun.nb_files + + if not backupset.backups.all(): # End :) + backupset.end_date = timezone.now() + backupset.status = 'done' + + bn = BackupNotification(type='bkpsetdone') + bn.message = "The backupset of type %s, started at %s, ended at %s (runned for %s hours) is now Done. %s files where copied for a total size of %s." % (backupset.type, str(backupset.start_date), str(backupset.end_date), str(backupset.get_total_time()), str(backupset.total_files), str(backupset.total_size)) + + bn.save() + bn.send_notifications() + + backupset.save() + + except Exception as e: + print("Error during check end of backup set !" + str(e)) + + l.release() diff --git a/backups/templates/backups/backupnotifications/list.html b/backups/templates/backups/backupnotifications/list.html new file mode 100644 index 0000000..0bb21ba --- /dev/null +++ b/backups/templates/backups/backupnotifications/list.html @@ -0,0 +1,102 @@ +{% extends "base.html" %} +{% load i18n %} + + +{% block title %}Backup notifications{% endblock %} + +{% block content %} + +

{% trans "Backups notifications" %}

+ + + +
+ +
+ +
+
+ + + + + + + + + + + {% for elem in liste %} + + + + + + {% endfor %} + +
{% trans "When" %}{% trans "Type" %}{% trans "Message" %}
{{elem.when}} ({{elem.when|timesince}}){{elem.get_type_display}}
{{elem.message}}
+ + + +
+
+
+
+ +
+ +
+
+ + + + + + {% for key, text, label in notif_types %} + + {% endfor %} + + + + {% for u, data in users_with_things %} + + + {% for key, has in data %} + + {% endfor %} + + + {% endfor %} + +
{% trans "User" %}{{text}}
{{u.get_full_name}}{{has|yesno}}
+
+
+
+ + + + +{% endblock %} diff --git a/backups/templates/backups/backupnotifications/switch.html b/backups/templates/backups/backupnotifications/switch.html new file mode 100644 index 0000000..4e5cd55 --- /dev/null +++ b/backups/templates/backups/backupnotifications/switch.html @@ -0,0 +1 @@ +{{is_ok|yesno}} diff --git a/backups/templates/backups/backups/_runs.html b/backups/templates/backups/backups/_runs.html index ed0d9e3..5a2b6de 100644 --- a/backups/templates/backups/backups/_runs.html +++ b/backups/templates/backups/backups/_runs.html @@ -11,6 +11,7 @@ {% trans "Start date" %} {% trans "End date" %} + {% trans "Type" %} {% trans "Size" %} {% trans "Nb files" %} {% trans "Stdout" %} @@ -22,6 +23,7 @@ {{elem.start_date|date:"Y/m/d"}} {{elem.start_date|time}} {% if elem.end_date %}{{elem.end_date|date}} {{elem.end_date|time}} ({{elem.end_date|timesince}}){% else %}{% trans "In progress or failled" %}{% endif %} + {{elem.get_type_display}} {{elem.size|filesizeformat}} {{elem.nb_files}}
{{elem.stdout|default:""}}
@@ -34,4 +36,4 @@ - \ No newline at end of file + diff --git a/backups/templates/backups/backups/list.html b/backups/templates/backups/backups/list.html index f6ab0f1..4da4aad 100644 --- a/backups/templates/backups/backups/list.html +++ b/backups/templates/backups/backups/list.html @@ -72,7 +72,7 @@

{% trans "Backups" %}

- {% trans "Cleanup >24h runs" %} + {% trans "Cleanup >24h runs not in a set" %} {% trans "Add" %}
diff --git a/backups/templates/backups/backupsets/list.html b/backups/templates/backups/backupsets/list.html new file mode 100644 index 0000000..795bece --- /dev/null +++ b/backups/templates/backups/backupsets/list.html @@ -0,0 +1,64 @@ +{% extends "base.html" %} +{% load i18n %} + + +{% block title %}Backup sets{% endblock %} + +{% block content %} + +

{% trans "Backups sets" %}

+ + + +
+ +
+ +
+
+ + + + + + + + + + + + + + + + {% for elem in liste %} + + + + + + + + + + + {% endfor %} + +
{% trans "Start date" %}{% trans "End date" %}{% trans "Type" %}{% trans "Status" %}{% trans "Total time" %}{% trans "Total size" %}{% trans "Total files" %}
{{elem.start_date}}{% if elem.end_date %}{{elem.end_date}} ({{elem.end_date|timesince}}){% endif %}{{elem.get_type_display}}{{elem.get_status_display}}{{elem.get_total_time}} hours{% if elem.type == 'hourly' %}{{elem.total_size|filesizeformat}}{% endif %}{% if elem.type == 'hourly' %}{{elem.total_files}}{% endif %} + {% if elem.status == 'running' %} + {% trans "Set as canceled" %} + {% endif %} +
+ + + +
+
+
+
+ +{% endblock %} diff --git a/backups/urls.py b/backups/urls.py index 99492f4..42820f7 100644 --- a/backups/urls.py +++ b/backups/urls.py @@ -13,5 +13,17 @@ url(r'^get_conf/(?P[0-9]*)/$', 'get_conf'), url(r'^clean_up$', 'clean_up'), + url(r'^clean_up_old_sets$', 'clean_up_old_sets'), + url(r'^runs$', 'backupsets_list'), + url(r'^runs/(?P[0-9]*)/cancel$', 'backupsets_cancel'), + + url(r'^notifications$', 'backupnotifications_list'), + url(r'^notifications/switch$', 'backupnotifications_switch'), + url(r'^notifications/cleanup$', 'clean_up_notifications'), + + url(r'^zabbix/list/_$', 'zabbix_list'), + url(r'^zabbix/last_hourly_duration/_$', 'zabbix_last_hourly_duration'), + url(r'^zabbix/last_(?P(hourly|weekly|daily|monthly))/(?P[0-9]*)$', 'zabbix_last_nb_hours'), + url(r'^zabbix/last_(?P(files|size))/(?P[0-9]*)$', 'zabbix_last_files_or_size'), ) diff --git a/backups/views.py b/backups/views.py index f74e0b7..b18c3a9 100644 --- a/backups/views.py +++ b/backups/views.py @@ -16,12 +16,15 @@ from django.core.urlresolvers import reverse from django.contrib import messages -from backups.models import Backup, BackupRun +from backups.models import Backup, BackupRun, BackupSetOfRun, BackupNotification, BackupUserWhoWantNotifs from backups.forms import BackupForm from backups.tasks import run_backup +from django.contrib.auth.models import User + from django.utils import timezone import datetime +import json @login_required @@ -167,8 +170,160 @@ def get_conf(request, pk): @staff_member_required def clean_up(request): - BackupRun.objects.filter(start_date__lt=timezone.now() - datetime.timedelta(days=1)).delete() + for b in BackupRun.objects.filter(start_date__lt=timezone.now() - datetime.timedelta(days=1)).all(): + if b.backupsetofrun_set.count() == 0: + b.delete() messages.success(request, "Old backups runs have been deleted") return HttpResponseRedirect(reverse('backups.views.backups_list')) + + +@login_required +@staff_member_required +def backupsets_list(request): + """Show the list of backup sets""" + + liste = BackupSetOfRun.objects.order_by('-start_date').all() + + return render_to_response('backups/backupsets/list.html', {'liste': liste}, context_instance=RequestContext(request)) + + +@login_required +@staff_member_required +def backupsets_cancel(request, pk): + + backupset = get_object_or_404(BackupSetOfRun, pk=pk, status='running') + backupset.status = 'canceled' + backupset.end_date = timezone.now() + backupset.save() + + bn = BackupNotification(type='bkpsetcanceled') + bn.message = "The backupset of type %s, started at %s, has been set as canceled." % (backupset.type, str(backupset.start_date), ) + bn.save() + bn.send_notifications() + + return HttpResponseRedirect(reverse('backups.views.backupsets_list')) + + +@login_required +@staff_member_required +def clean_up_old_sets(request): + + NB_OK = {'hourly': 6, 'daily': 7, 'weekly': 7, 'monthly': 3} + + for b in BackupSetOfRun.objects.order_by('-start_date').all(): + if NB_OK[b.type] >= 0: + NB_OK[b.type] -= 1 + else: + b.delete() + + messages.success(request, "Old backups sets have been deleted") + + return HttpResponseRedirect(reverse('backups.views.backupsets_list')) + + +@login_required +@staff_member_required +def backupnotifications_list(request): + """Show the list of backup notifications""" + + liste = BackupNotification.objects.order_by('-when').all() + + notif_types = BackupNotification.get_types_with_labels() + + users_with_things = [] + + for u in User.objects.order_by('username').all(): + data = [] + + for key, __, __ in notif_types: + data.append((key, BackupUserWhoWantNotifs.objects.filter(type=key, user=u).count() > 0)) + + users_with_things.append((u, data)) + + return render_to_response('backups/backupnotifications/list.html', {'liste': liste, 'notif_types': notif_types, 'users_with_things': users_with_things}, context_instance=RequestContext(request)) + + +@login_required +@staff_member_required +def backupnotifications_switch(request): + """Switch a backup notification""" + + (obj, created) = BackupUserWhoWantNotifs.objects.get_or_create(type=request.GET.get('key'), user=get_object_or_404(User, pk=request.GET.get('uPk'))) + + if not created: + obj.delete() + + return render_to_response('backups/backupnotifications/switch.html', {'is_ok': created}, context_instance=RequestContext(request)) + + +@login_required +@staff_member_required +def clean_up_notifications(request): + + for b in BackupNotification.objects.filter(when__lt=timezone.now() - datetime.timedelta(days=15)).all(): + b.delete() + + messages.success(request, "Old notifications have been deleted") + + return HttpResponseRedirect(reverse('backups.views.backupnotifications_list')) + + +def zabbix_list(request): + + data = [] + + for b in Backup.objects.filter(active=True).all(): + data.append({'{#BACKUP_ID}': b.pk, '{#BACKUP_NAME}': b.name}) + + # return HttpResponse(build_zabbix_json(data)) + return HttpResponse(json.dumps({'data': data})) + + +def zabbix_last_nb_hours(request, pk, mode): + + backup = get_object_or_404(Backup, pk=pk) + + elem = backup.backuprun_set.order_by('-start_date').exclude(end_date=None).filter(type=mode) + + if elem.count() == 0: + return HttpResponse('0') + + last_elem = elem.all()[0] + + diff = (timezone.now() - last_elem.start_date).total_seconds() / 3600.0 + + diff = int(diff) + + if diff == 0: + diff = 1 + + return HttpResponse(str(diff)) + + +def zabbix_last_files_or_size(request, pk, mode): + + + backup = get_object_or_404(Backup, pk=pk) + + elem = backup.backuprun_set.order_by('-start_date').exclude(end_date=None).filter(type='hourly') + + if elem.count() == 0: + return HttpResponse('0') + + last_elem = elem.all()[0] + + val = last_elem.size if mode == 'size' else last_elem.nb_files + + return HttpResponse(str(val)) + + +def zabbix_last_hourly_duration(request): + + bs = BackupSetOfRun.objects.filter(type='hourly', status='done').exclude(total_size=0).order_by('-start_date') + + if bs.count(): + return HttpResponse(str(bs.get_total_time())) + + return HttpResponse("0") diff --git a/doc/setup.md b/doc/setup.md index a3487fb..d4f18ac 100644 --- a/doc/setup.md +++ b/doc/setup.md @@ -116,4 +116,11 @@ Update `settingsLocal.py`: Add a portforwarding entry to your ngnix server, from port 443 to port 443. -You can now add hostnameforwarding entry from the port 443 to your server (using port 80 as destination !). \ No newline at end of file +You can now add hostnameforwarding entry from the port 443 to your server (using port 80 as destination !). + +## Zabbix + +To monitor backups with zabbix, add this to one of your zabbix agent +`UserParameter=azimutgestion.[*],wget http://GESTION_HOST/backups/zabbix/$1/$2 -O - -o /dev/null` + +and use the zabbix template 'Azmiut-gestion: Backups' diff --git a/doc/zabbix_template.xml b/doc/zabbix_template.xml new file mode 100644 index 0000000..29f9dc7 --- /dev/null +++ b/doc/zabbix_template.xml @@ -0,0 +1,464 @@ + + + 2.0 + 2014-06-18T16:29:35Z + + + Templates + + + + + + + + {AzimutGestionBackups:azimutgestion.[last_hourly_duration,_].last(0)}>4.0 + Last hourly set was too slow + + 0 + 3 + + 0 + + + + diff --git a/main/templates/main/_backupset.html b/main/templates/main/_backupset.html new file mode 100644 index 0000000..c825b21 --- /dev/null +++ b/main/templates/main/_backupset.html @@ -0,0 +1,9 @@ +{% if b %} + + {{b.get_type_display}} + {{b.start_date|timesince}} + {{b.get_status_display}} + {{b.get_total_time}} hours + {% if b.type == 'hourly' %}{{b.total_size|filesizeformat}}{% endif %} + +{% endif %} diff --git a/main/templates/main/_backupsets.html b/main/templates/main/_backupsets.html new file mode 100644 index 0000000..82be248 --- /dev/null +++ b/main/templates/main/_backupsets.html @@ -0,0 +1,22 @@ +{% load i18n %} + +
+ + +
+ + + + {% with last_hourlys.0 as b %}{% include "main/_backupset.html" %}{% endwith %} + {% with last_hourlys.1 as b %}{% include "main/_backupset.html" %}{% endwith %} + {% with last_daily.0 as b %}{% include "main/_backupset.html" %}{% endwith %} + {% with last_daily.1 as b %}{% include "main/_backupset.html" %}{% endwith %} + {% with last_weekly.0 as b %}{% include "main/_backupset.html" %}{% endwith %} + {% with last_weekly.1 as b %}{% include "main/_backupset.html" %}{% endwith %} + {% with last_monthly.0 as b %}{% include "main/_backupset.html" %}{% endwith %} + {% with last_monthly.1 as b %}{% include "main/_backupset.html" %}{% endwith %} +
{% trans "Type" %}{% trans "Last backup" %}{% trans "Status" %}{% trans "Total time" %}Size
+
+
diff --git a/main/templates/main/home.html b/main/templates/main/home.html index 8ef74ea..5489684 100644 --- a/main/templates/main/home.html +++ b/main/templates/main/home.html @@ -14,6 +14,7 @@

{% trans "Welcome !" %}

+ {% include "main/_backupsets.html" %} {% include "main/_backups.html" %}
@@ -21,4 +22,4 @@

{% trans "Welcome !" %}

-{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/main/views.py b/main/views.py index 36c118c..2d14dad 100644 --- a/main/views.py +++ b/main/views.py @@ -23,7 +23,7 @@ from main.models import SshKey from groups.models import Group from main.tasks import update_git_repo -from backups.models import Backup +from backups.models import Backup, BackupSetOfRun from servers.models import Server @@ -48,7 +48,12 @@ def home(request): backups = Backup.objects.order_by('name').all() - return render_to_response('main/home.html', {'backups': backups}, context_instance=RequestContext(request)) + last_hourlys = BackupSetOfRun.objects.order_by('-start_date').filter(type='hourly').all() + last_daily = BackupSetOfRun.objects.order_by('-start_date').filter(type='daily').all() + last_weekly = BackupSetOfRun.objects.order_by('-start_date').filter(type='weekly').all() + last_monthly = BackupSetOfRun.objects.order_by('-start_date').filter(type='monthly').all() + + return render_to_response('main/home.html', {'backups': backups, 'last_daily': last_daily, 'last_weekly': last_weekly, 'last_hourlys': last_hourlys, 'last_monthly': last_monthly}, context_instance=RequestContext(request)) @login_required diff --git a/templates/base.html b/templates/base.html index 16e6d86..ab0d1d3 100644 --- a/templates/base.html +++ b/templates/base.html @@ -118,6 +118,12 @@ + +