commit b6426ead31776c8dc13af0e1a235ef67ba95e67d
Author: Ilias Tsitsimpis <iliastsi@grnet.gr>
Date:   Tue Mar 4 13:00:00 2014 +0200

    Use SynnefoCommand for django-admin commands
    
    Instead of django's BaseCommand class, use out SynnefoCommand which
    takes care of logging the command and its output.
    
    Issue #4948: Log all stdout/stderr for snf-manage invocations

diff --git a/snf-astakos-app/astakos/im/management/commands/authpolicy-add.py b/snf-astakos-app/astakos/im/management/commands/authpolicy-add.py
index a5469b6..0377914 100644
--- a/snf-astakos-app/astakos/im/management/commands/authpolicy-add.py
+++ b/snf-astakos-app/astakos/im/management/commands/authpolicy-add.py
@@ -35,11 +35,12 @@ import string
 
 from optparse import make_option
 
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
 
 from astakos.im.models import AuthProviderPolicyProfile as Profile
+from snf_django.management.commands import SynnefoCommand
 
-option_list = list(BaseCommand.option_list) + [
+option_list = list(SynnefoCommand.option_list) + [
     make_option('--update',
                 action='store_true',
                 dest='update',
@@ -68,7 +69,7 @@ for p in POLICIES:
                                    help="%s policy" % p.title()))
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     args = "<name> <provider_name>"
     help = "Create a new authentication provider policy profile"
     option_list = option_list
diff --git a/snf-astakos-app/astakos/im/management/commands/authpolicy-remove.py b/snf-astakos-app/astakos/im/management/commands/authpolicy-remove.py
index 8cbe367..9740cfd 100644
--- a/snf-astakos-app/astakos/im/management/commands/authpolicy-remove.py
+++ b/snf-astakos-app/astakos/im/management/commands/authpolicy-remove.py
@@ -31,16 +31,17 @@
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.
 
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
 
 from astakos.im.models import AuthProviderPolicyProfile as Profile
+from snf_django.management.commands import SynnefoCommand
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     args = "<profile_name>"
     help = "Remove an authentication provider policy"
 
-    option_list = BaseCommand.option_list + ()
+    option_list = SynnefoCommand.option_list + ()
 
     def handle(self, *args, **options):
         if len(args) != 1:
diff --git a/snf-astakos-app/astakos/im/management/commands/authpolicy-set.py b/snf-astakos-app/astakos/im/management/commands/authpolicy-set.py
index b6f88e6..2dfd896 100644
--- a/snf-astakos-app/astakos/im/management/commands/authpolicy-set.py
+++ b/snf-astakos-app/astakos/im/management/commands/authpolicy-set.py
@@ -34,12 +34,13 @@
 from optparse import make_option
 
 from django.db import transaction
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
 
+from snf_django.management.commands import SynnefoCommand
 from astakos.im.models import AuthProviderPolicyProfile as Profile
 from astakos.im.models import AstakosUser, Group
 
-option_list = BaseCommand.option_list + (
+option_list = SynnefoCommand.option_list + (
     make_option('--group',
                 action='append',
                 dest='groups',
@@ -63,7 +64,7 @@ def update_profile(profile, users, groups):
     profile.users.add(*users)
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     args = "<name> <provider_name>"
     help = "Assign an existing authentication provider policy profile to " + \
            "a user or group. All previously set "
diff --git a/snf-astakos-app/astakos/im/management/commands/cleanup-full.py b/snf-astakos-app/astakos/im/management/commands/cleanup-full.py
index f36dccb..f7d8dbd 100644
--- a/snf-astakos-app/astakos/im/management/commands/cleanup-full.py
+++ b/snf-astakos-app/astakos/im/management/commands/cleanup-full.py
@@ -32,15 +32,15 @@
 # or implied, of GRNET S.A.
 
 
-from django.core.management.base import NoArgsCommand
 from django.core.management import call_command
 from django.utils.importlib import import_module
 from django.conf import settings
 
 from astakos.im.models import SessionCatalog
+from snf_django.management.commands import SynnefoCommand
 
 
-class Command(NoArgsCommand):
+class Command(SynnefoCommand):
     help = "Cleanup sessions and session catalog"
 
     def handle_noargs(self, **options):
diff --git a/snf-astakos-app/astakos/im/management/commands/component-add.py b/snf-astakos-app/astakos/im/management/commands/component-add.py
index 538234f..3ab9d19 100644
--- a/snf-astakos-app/astakos/im/management/commands/component-add.py
+++ b/snf-astakos-app/astakos/im/management/commands/component-add.py
@@ -32,15 +32,17 @@
 # or implied, of GRNET S.A.
 
 from optparse import make_option
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
+
 from astakos.im.models import Component
+from snf_django.management.commands import SynnefoCommand
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     args = "<name>"
     help = "Register a component"
 
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option('--ui-url',
                     dest='ui_url',
                     default=None,
diff --git a/snf-astakos-app/astakos/im/management/commands/component-modify.py b/snf-astakos-app/astakos/im/management/commands/component-modify.py
index 6443fb4..1c464ce 100644
--- a/snf-astakos-app/astakos/im/management/commands/component-modify.py
+++ b/snf-astakos-app/astakos/im/management/commands/component-modify.py
@@ -33,16 +33,17 @@
 
 from optparse import make_option
 
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
 
 from astakos.im.models import Component
+from snf_django.management.commands import SynnefoCommand
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     args = "<component ID or name>"
     help = "Modify component attributes"
 
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option('--ui-url',
                     dest='ui_url',
                     default=None,
diff --git a/snf-astakos-app/astakos/im/management/commands/component-remove.py b/snf-astakos-app/astakos/im/management/commands/component-remove.py
index b6db662..6aa067e 100644
--- a/snf-astakos-app/astakos/im/management/commands/component-remove.py
+++ b/snf-astakos-app/astakos/im/management/commands/component-remove.py
@@ -31,12 +31,14 @@
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.
 
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
 from django.db import transaction
+
 from astakos.im.models import Component
+from snf_django.management.commands import SynnefoCommand
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     args = "<component ID or name>"
     help = "Remove a component along with its registered services"
 
diff --git a/snf-astakos-app/astakos/im/management/commands/fix-superusers.py b/snf-astakos-app/astakos/im/management/commands/fix-superusers.py
index 6fda2a4..c62821a 100644
--- a/snf-astakos-app/astakos/im/management/commands/fix-superusers.py
+++ b/snf-astakos-app/astakos/im/management/commands/fix-superusers.py
@@ -31,16 +31,14 @@
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.
 
-from optparse import make_option
-from datetime import datetime
-
 from django.db import transaction
-from django.core.management.base import NoArgsCommand, CommandError
+from django.core.management.base import CommandError
 
 from astakos.im.auth import fix_superusers
+from snf_django.management.commands import SynnefoCommand
 
 
-class Command(NoArgsCommand):
+class Command(SynnefoCommand):
     help = "Transform superusers created by syncdb into AstakosUser instances"
 
     @transaction.commit_on_success
diff --git a/snf-astakos-app/astakos/im/management/commands/group-add.py b/snf-astakos-app/astakos/im/management/commands/group-add.py
index 7bbeb16..77e1904 100644
--- a/snf-astakos-app/astakos/im/management/commands/group-add.py
+++ b/snf-astakos-app/astakos/im/management/commands/group-add.py
@@ -31,16 +31,17 @@
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.
 
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
 
 from astakos.im.models import Group
+from snf_django.management.commands import SynnefoCommand
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     args = "<group name>"
     help = "Create a group with the given name"
 
-    option_list = BaseCommand.option_list + ()
+    option_list = SynnefoCommand.option_list + ()
 
     def handle(self, *args, **options):
         if len(args) != 1:
diff --git a/snf-astakos-app/astakos/im/management/commands/project-control.py b/snf-astakos-app/astakos/im/management/commands/project-control.py
index d167249..ebd9c81 100644
--- a/snf-astakos-app/astakos/im/management/commands/project-control.py
+++ b/snf-astakos-app/astakos/im/management/commands/project-control.py
@@ -34,16 +34,18 @@
 from optparse import make_option
 
 from django.db import transaction
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
+
 from astakos.im.functions import (terminate, suspend, unsuspend,
                                   reinstate, check_expiration,
                                   approve_application, deny_application)
+from snf_django.management.commands import SynnefoCommand
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     help = "Manage projects and applications"
 
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option('--approve',
                     dest='approve',
                     metavar='<application id>',
diff --git a/snf-astakos-app/astakos/im/management/commands/project-modify.py b/snf-astakos-app/astakos/im/management/commands/project-modify.py
index 0c0d2c7..14ced4b 100644
--- a/snf-astakos-app/astakos/im/management/commands/project-modify.py
+++ b/snf-astakos-app/astakos/im/management/commands/project-modify.py
@@ -34,7 +34,7 @@
 from optparse import make_option
 
 from django.db.models import Q
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
 from django.db import transaction
 from synnefo.util import units
 from astakos.im import functions
@@ -43,6 +43,7 @@ import astakos.api.projects as api
 import synnefo.util.date as date_util
 from snf_django.management import utils
 from astakos.im.management.commands import _common
+from snf_django.management.commands import SynnefoCommand
 
 
 def make_policies(limits):
@@ -112,10 +113,10 @@ def make_options():
     return tuple(options)
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     args = "<project id> (or --all-base-projects)"
     help = "Modify an already initialized project"
-    option_list = BaseCommand.option_list + make_options() + (
+    option_list = SynnefoCommand.option_list + make_options() + (
         make_option('--all-base-projects',
                     action='store_true',
                     default=False,
diff --git a/snf-astakos-app/astakos/im/management/commands/reconcile-resources-astakos.py b/snf-astakos-app/astakos/im/management/commands/reconcile-resources-astakos.py
index 20b3066..e660d28 100644
--- a/snf-astakos-app/astakos/im/management/commands/reconcile-resources-astakos.py
+++ b/snf-astakos-app/astakos/im/management/commands/reconcile-resources-astakos.py
@@ -34,7 +34,7 @@
 from optparse import make_option
 from datetime import datetime
 
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
 from django.db import transaction
 
 from snf_django.utils import reconcile
@@ -44,9 +44,10 @@ from astakos.im import quotas
 from astakos.im.functions import count_pending_app
 import astakos.quotaholder_app.callpoint as qh
 import astakos.quotaholder_app.exception as qh_exception
+from snf_django.management.commands import SynnefoCommand
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     help = """Reconcile resource usage of Quotaholder with Astakos DB.
 
     Detect unsynchronized usage between Quotaholder and Astakos DB resources
@@ -54,7 +55,7 @@ class Command(BaseCommand):
 
     """
 
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option("--userid", dest="userid",
                     default=None,
                     help="Reconcile resources only for this user"),
@@ -78,7 +79,7 @@ class Command(BaseCommand):
         userid = options['userid']
         project = options['project']
 
-        RESOURCES = [quotas.PENDING_APP_RESOURCE]
+        resources = [quotas.PENDING_APP_RESOURCE]
 
         try:
             astakos = Component.objects.get(name="astakos")
@@ -109,11 +110,11 @@ class Command(BaseCommand):
             db_project_holdings.update(user_holdings)
 
         unsynced_users, users_pending, users_unknown =\
-            reconcile.check_users(self.stderr, RESOURCES,
+            reconcile.check_users(self.stderr, resources,
                                   db_holdings, qh_holdings)
 
         unsynced_projects, projects_pending, projects_unknown =\
-            reconcile.check_projects(self.stderr, RESOURCES,
+            reconcile.check_projects(self.stderr, resources,
                                      db_project_holdings, qh_project_holdings)
         pending_exists = users_pending or projects_pending
         unknown_exists = users_unknown or projects_unknown
diff --git a/snf-astakos-app/astakos/im/management/commands/resource-modify.py b/snf-astakos-app/astakos/im/management/commands/resource-modify.py
index 91233a6..e3d9b15 100644
--- a/snf-astakos-app/astakos/im/management/commands/resource-modify.py
+++ b/snf-astakos-app/astakos/im/management/commands/resource-modify.py
@@ -32,19 +32,20 @@
 # or implied, of GRNET S.A.
 
 from optparse import make_option
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
 
 from snf_django.management import utils
 from astakos.im.models import Resource
 from astakos.im import register
 from ._common import style_options, check_style, units
+from snf_django.management.commands import SynnefoCommand
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     args = "<resource name>"
     help = "Modify a resource's quota defaults and boolean flags."
 
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option('--base-default',
                     metavar='<limit>',
                     help="Specify default quota for base projects"),
diff --git a/snf-astakos-app/astakos/im/management/commands/service-export-astakos.py b/snf-astakos-app/astakos/im/management/commands/service-export-astakos.py
index 96cb2ce..52dbbe7 100644
--- a/snf-astakos-app/astakos/im/management/commands/service-export-astakos.py
+++ b/snf-astakos-app/astakos/im/management/commands/service-export-astakos.py
@@ -32,13 +32,14 @@
 # or implied, of GRNET S.A.
 
 from django.utils import simplejson as json
-from django.core.management.base import NoArgsCommand
 # import from settings, after any post-processing
+
 from astakos.im.settings import astakos_services
 from synnefo.lib.services import filter_public
+from snf_django.management.commands import SynnefoCommand
 
 
-class Command(NoArgsCommand):
+class Command(SynnefoCommand):
     help = "Export Astakos services in JSON format."
 
     def handle(self, *args, **options):
diff --git a/snf-astakos-app/astakos/im/management/commands/service-import.py b/snf-astakos-app/astakos/im/management/commands/service-import.py
index d2a1b3d..b64648b 100644
--- a/snf-astakos-app/astakos/im/management/commands/service-import.py
+++ b/snf-astakos-app/astakos/im/management/commands/service-import.py
@@ -34,18 +34,19 @@
 from optparse import make_option
 
 from django.db import transaction
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
 from django.utils import simplejson as json
 
 from astakos.im.register import add_service, add_resource, RegisterException
+from snf_django.management.commands import SynnefoCommand
 from astakos.im.models import Component
 from ._common import read_from_file
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     help = "Register services"
 
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option('--json',
                     dest='json',
                     metavar='<json.file>',
diff --git a/snf-astakos-app/astakos/im/management/commands/term-add.py b/snf-astakos-app/astakos/im/management/commands/term-add.py
index 89e6842..196530a 100644
--- a/snf-astakos-app/astakos/im/management/commands/term-add.py
+++ b/snf-astakos-app/astakos/im/management/commands/term-add.py
@@ -33,13 +33,14 @@
 
 from os.path import abspath
 
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
 from django.db import transaction
 
 from astakos.im.models import ApprovalTerms, AstakosUser
+from snf_django.management.commands import SynnefoCommand
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     args = "<location>"
     help = "Insert approval terms"
 
diff --git a/snf-astakos-app/astakos/im/management/commands/user-activation-send.py b/snf-astakos-app/astakos/im/management/commands/user-activation-send.py
index b7b06ed..ca09cae 100644
--- a/snf-astakos-app/astakos/im/management/commands/user-activation-send.py
+++ b/snf-astakos-app/astakos/im/management/commands/user-activation-send.py
@@ -31,15 +31,16 @@
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.
 
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
 
 from astakos.im import activation_backends
 activation_backend = activation_backends.get_backend()
 
 from ._common import get_user
+from snf_django.management.commands import SynnefoCommand
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     args = "<user ID or email> [user ID or email] ..."
     help = "Sends an activation email to one or more users"
 
diff --git a/snf-astakos-app/astakos/im/management/commands/user-add.py b/snf-astakos-app/astakos/im/management/commands/user-add.py
index 16ca7cd..093ed4d 100644
--- a/snf-astakos-app/astakos/im/management/commands/user-add.py
+++ b/snf-astakos-app/astakos/im/management/commands/user-add.py
@@ -32,22 +32,22 @@
 # or implied, of GRNET S.A.
 
 from optparse import make_option
-from datetime import datetime
 
 from django.db import transaction
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
 from django.core.validators import validate_email
 from django.core.exceptions import ValidationError
 
 from astakos.im.models import AstakosUser, get_latest_terms
+from snf_django.management.commands import SynnefoCommand
 from astakos.im.auth import make_local_user
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     args = "<email> <first name> <last name>"
     help = "Create a user"
 
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option('--password',
                     dest='password',
                     metavar='PASSWORD',
diff --git a/snf-astakos-app/astakos/im/management/commands/user-modify.py b/snf-astakos-app/astakos/im/management/commands/user-modify.py
index cd1b783..14ef6ee 100644
--- a/snf-astakos-app/astakos/im/management/commands/user-modify.py
+++ b/snf-astakos-app/astakos/im/management/commands/user-modify.py
@@ -38,23 +38,24 @@ from optparse import make_option
 
 from django.core import management
 from django.db import transaction
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
 from django.contrib.auth.models import Group
 from django.core.exceptions import ValidationError
 from django.core.validators import validate_email
 
 from astakos.im.models import AstakosUser
 from astakos.im import activation_backends
+from snf_django.management.commands import SynnefoCommand
 from ._common import (remove_user_permission, add_user_permission, is_uuid)
 
 activation_backend = activation_backends.get_backend()
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     args = "<user ID> (or --all)"
     help = "Modify a user's attributes"
 
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option('--all',
                     action='store_true',
                     default=False,
diff --git a/snf-astakos-app/astakos/oa2/management/commands/oauth2-client-remove.py b/snf-astakos-app/astakos/oa2/management/commands/oauth2-client-remove.py
index a4075c2..7ee9b93 100644
--- a/snf-astakos-app/astakos/oa2/management/commands/oauth2-client-remove.py
+++ b/snf-astakos-app/astakos/oa2/management/commands/oauth2-client-remove.py
@@ -31,12 +31,14 @@
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.
 
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
 from django.db import transaction
+
+from snf_django.management.commands import SynnefoCommand
 from astakos.oa2.models import Client
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     args = "<client ID or identifier>"
     help = "Remove an oauth2 client along with its registered redirect urls"
 
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/backend-add.py b/snf-cyclades-app/synnefo/logic/management/commands/backend-add.py
index 676e8dd..95729f8 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/backend-add.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/backend-add.py
@@ -28,11 +28,12 @@
 # policies, either expressed or implied, of GRNET S.A.
 #
 from optparse import make_option
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
 
 from synnefo.db.models import Backend, Network
 from django.db.utils import IntegrityError
 from synnefo.logic import backend as backend_mod
+from snf_django.management.commands import SynnefoCommand
 from synnefo.management.common import check_backend_credentials
 from snf_django.management.utils import pprint_table
 
@@ -40,11 +41,11 @@ from snf_django.management.utils import pprint_table
 HYPERVISORS = [h[0] for h in Backend.HYPERVISORS]
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     can_import_settings = True
 
     help = 'Create a new backend.'
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option('--clustername', dest='clustername'),
         make_option('--port', dest='port', default=5080),
         make_option('--user', dest='username'),
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/backend-modify.py b/snf-cyclades-app/synnefo/logic/management/commands/backend-modify.py
index 5befd67..fdca4e2 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/backend-modify.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/backend-modify.py
@@ -32,7 +32,9 @@
 # or implied, of GRNET S.A.
 
 from optparse import make_option
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
+
+from snf_django.management.commands import SynnefoCommand
 from synnefo.db.models import Backend
 from snf_django.management.utils import parse_bool
 from synnefo.management import common
@@ -40,12 +42,12 @@ from synnefo.management import common
 HYPERVISORS = [h[0] for h in Backend.HYPERVISORS]
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     output_transaction = True
     args = "<backend ID>"
     help = "Modify a backend"
 
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option('--clustername',
                     dest='clustername',
                     help="Set backend's clustername"),
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/backend-remove.py b/snf-cyclades-app/synnefo/logic/management/commands/backend-remove.py
index e034813..6f635b4 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/backend-remove.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/backend-remove.py
@@ -28,7 +28,9 @@
 # policies, either expressed or implied, of GRNET S.A.
 #
 
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
+
+from snf_django.management.commands import SynnefoCommand
 from synnefo.management import common
 from synnefo.logic import backend as backend_mod
 from synnefo.db.models import Backend
@@ -42,7 +44,7 @@ this Backend.  Removal of a backend will fail if the backend hosts any
 non-deleted instances."""
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     help = HELP_MSG
 
     def handle(self, *args, **options):
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/backend-update-status.py b/snf-cyclades-app/synnefo/logic/management/commands/backend-update-status.py
index b54a9ee..5631989 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/backend-update-status.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/backend-update-status.py
@@ -27,8 +27,7 @@
 # those of the authors and should not be interpreted as representing official
 # policies, either expressed or implied, of GRNET S.A.
 #
-from django.core.management.base import BaseCommand
-
+from snf_django.management.commands import SynnefoCommand
 from synnefo.db.models import Backend
 from synnefo.logic import backend as backend_mod
 
@@ -41,7 +40,7 @@ This command updates:
 """
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     help = HELP_MSG
 
     def handle(self, **options):
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/cyclades-astakos-migrate-013.py b/snf-cyclades-app/synnefo/logic/management/commands/cyclades-astakos-migrate-013.py
index d15ffe6..800a77c 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/cyclades-astakos-migrate-013.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/cyclades-astakos-migrate-013.py
@@ -36,10 +36,11 @@ import functools
 
 from optparse import make_option
 
-from django.core.management.base import CommandError, BaseCommand
+from django.core.management.base import CommandError
 from django.db import transaction
 from django.conf import settings
 
+from snf_django.management.commands import SynnefoCommand
 from synnefo.api.util import get_existing_users
 from synnefo.lib.utils import case_unique
 from synnefo.db.models import Network, VirtualMachine
@@ -90,10 +91,10 @@ def migrate_user(username, uuid):
         key.save()
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     help = "Quotas migration helper"
 
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option('--strict',
                     dest='strict',
                     action="store_false",
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/flavor-create.py b/snf-cyclades-app/synnefo/logic/management/commands/flavor-create.py
index a69d7fc..0bc2518 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/flavor-create.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/flavor-create.py
@@ -34,15 +34,16 @@
 from itertools import product
 from optparse import make_option
 
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
 
+from snf_django.management.commands import SynnefoCommand
 from synnefo.db.models import Flavor
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     output_transaction = True
 
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option("-n", "--dry-run", dest="dry_run", action="store_true"),
     )
     args = "<cpu>[,<cpu>,...] " \
@@ -83,7 +84,8 @@ class Command(BaseCommand):
                     self.stdout.write("Flavor '%s' already exists\n"
                                       % flavor.name)
                     if flavor.deleted:
-                        msg = "Flavor '%s' is marked as deleted. Use"\
-                        " 'snf-manage flavor-modify' to restore this flavor\n"\
-                        % flavor.name
+                        msg = "Flavor '%s' is marked as deleted." \
+                              " Use 'snf-manage flavor-modify' to" \
+                              " restore this flavor\n" \
+                              % flavor.name
                         self.stdout.write(msg)
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/flavor-modify.py b/snf-cyclades-app/synnefo/logic/management/commands/flavor-modify.py
index 4255061..5f81762 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/flavor-modify.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/flavor-modify.py
@@ -33,7 +33,9 @@
 
 from optparse import make_option
 
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
+
+from snf_django.management.commands import SynnefoCommand
 from synnefo.management.common import get_resource
 from snf_django.management.utils import parse_bool
 
@@ -42,11 +44,11 @@ from logging import getLogger
 log = getLogger(__name__)
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     args = "<flavor id>"
     help = "Modify a flavor"
 
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option(
             "--deleted",
             dest="deleted",
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/floating-ip-attach.py b/snf-cyclades-app/synnefo/logic/management/commands/floating-ip-attach.py
index f5265f1..1c0952e 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/floating-ip-attach.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/floating-ip-attach.py
@@ -33,15 +33,17 @@
 
 from optparse import make_option
 
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
+
+from snf_django.management.commands import SynnefoCommand
 from synnefo.management import common
 from synnefo.logic import servers
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     help = "Attach a floating IP to a VM or router"
 
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option(
             '--machine',
             dest='machine',
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/floating-ip-create.py b/snf-cyclades-app/synnefo/logic/management/commands/floating-ip-create.py
index 291f141..902f8c1 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/floating-ip-create.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/floating-ip-create.py
@@ -33,16 +33,18 @@
 
 from optparse import make_option
 
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
+
+from snf_django.management.commands import SynnefoCommand
 from synnefo.management.common import convert_api_faults
 from synnefo.logic import ips
 from synnefo.api import util
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     help = "Allocate a new floating IP"
 
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option(
             '--network',
             dest='network_id',
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/floating-ip-detach.py b/snf-cyclades-app/synnefo/logic/management/commands/floating-ip-detach.py
index e2371a6..46d3cec 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/floating-ip-detach.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/floating-ip-detach.py
@@ -33,12 +33,14 @@
 
 #from optparse import make_option
 
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
+
+from snf_django.management.commands import SynnefoCommand
 from synnefo.management import common
 from synnefo.logic import servers
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     help = "Detach a floating IP from a VM or router"
 
     @common.convert_api_faults
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/network-create.py b/snf-cyclades-app/synnefo/logic/management/commands/network-create.py
index 75b6dc6..46a960e 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/network-create.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/network-create.py
@@ -33,7 +33,9 @@
 
 from optparse import make_option
 
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
+
+from snf_django.management.commands import SynnefoCommand
 from synnefo.management.common import convert_api_faults
 from snf_django.management.utils import parse_bool
 
@@ -41,18 +43,17 @@ from synnefo.db.models import Network
 from synnefo.logic import networks, subnets
 from synnefo.management import pprint
 
-import ipaddr
 
 NETWORK_FLAVORS = Network.FLAVORS.keys()
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     can_import_settings = True
     output_transaction = True
 
     help = "Create a new network"
 
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option(
             '--name',
             dest='name',
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/network-inspect.py b/snf-cyclades-app/synnefo/logic/management/commands/network-inspect.py
index 8a033f4..1ac30e9 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/network-inspect.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/network-inspect.py
@@ -33,15 +33,17 @@
 
 from optparse import make_option
 
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
+
+from snf_django.management.commands import SynnefoCommand
 from synnefo.management import pprint, common
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     help = "Inspect a network on DB and Ganeti."
     args = "<Network ID>"
 
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option(
             '--displayname',
             action='store_true',
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/network-modify.py b/snf-cyclades-app/synnefo/logic/management/commands/network-modify.py
index 0298b1f..a1280ec 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/network-modify.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/network-modify.py
@@ -33,20 +33,21 @@
 
 from optparse import make_option
 
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
 
 from synnefo.db.models import Backend
 from synnefo.management.common import get_resource
+from snf_django.management.commands import SynnefoCommand
 from snf_django.management.utils import parse_bool
 from synnefo.logic import networks, backend as backend_mod
 from django.db import transaction
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     args = "<Network ID>"
     help = "Modify a network."
 
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option(
             '--name',
             dest='name',
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/pool-create.py b/snf-cyclades-app/synnefo/logic/management/commands/pool-create.py
index 1eb5974..a357080 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/pool-create.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/pool-create.py
@@ -31,18 +31,20 @@
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.
 
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
 from optparse import make_option
+
+from snf_django.management.commands import SynnefoCommand
 from synnefo.db.utils import validate_mac
 from synnefo.management.common import pool_table_from_type
 
 POOL_CHOICES = ['bridge', 'mac-prefix']
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     help = "Create a new pool of resources."
     output_transaction = True
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option("--type", dest="type",
                     choices=POOL_CHOICES,
                     help="Type of pool. Choices:"
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/pool-list.py b/snf-cyclades-app/synnefo/logic/management/commands/pool-list.py
index 640f79d..f66ec34 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/pool-list.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/pool-list.py
@@ -30,18 +30,17 @@
 # documentation are those of the authors and should not be
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.
-
-from django.core.management.base import BaseCommand
 from optparse import make_option
+from snf_django.management.commands import SynnefoCommand
 from synnefo.management.common import pool_table_from_type
 
 POOL_CHOICES = ['bridge', 'mac-prefix']
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     help = "List available pools"
     output_transaction = True
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option('--type', dest='type',
                     choices=POOL_CHOICES,
                     help="Type of pool"
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/pool-modify.py b/snf-cyclades-app/synnefo/logic/management/commands/pool-modify.py
index 7388f1e..40853d6 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/pool-modify.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/pool-modify.py
@@ -31,18 +31,20 @@
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.
 
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
 from optparse import make_option
+
+from snf_django.management.commands import SynnefoCommand
 from synnefo.management.common import pool_table_from_type
 
 POOL_CHOICES = ['bridge', 'mac-prefix']
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     args = "<pool ID>"
     help = "Modify a pool"
     output_transaction = True
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option('--type', dest='type',
                     choices=POOL_CHOICES,
                     help="Type of pool"
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/pool-show.py b/snf-cyclades-app/synnefo/logic/management/commands/pool-show.py
index 4085893..bacddb8 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/pool-show.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/pool-show.py
@@ -31,20 +31,21 @@
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.
 
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
 from optparse import make_option
 
 from synnefo.db.pools import bitarray_to_map
 from synnefo.management import pprint, common
+from snf_django.management.commands import SynnefoCommand
 
 POOL_CHOICES = ['bridge', 'mac-prefix']
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     args = "<pool ID>"
     help = "Show a pool"
     output_transaction = True
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option('--type', dest='type',
                     choices=POOL_CHOICES,
                     help="Type of pool"
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/port-create.py b/snf-cyclades-app/synnefo/logic/management/commands/port-create.py
index 63b1cb0..b5f890d 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/port-create.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/port-create.py
@@ -33,11 +33,12 @@
 
 from optparse import make_option
 
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
 
 from synnefo.api import util
 from synnefo.management import common, pprint
 from snf_django.management.utils import parse_bool
+from snf_django.management.commands import SynnefoCommand
 from synnefo.logic import servers
 
 HELP_MSG = """Create a new port.
@@ -48,10 +49,10 @@ Otherwise, the port will get an IP address for each Subnet that is associated
 with the network."""
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     help = HELP_MSG
 
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option(
             "--name",
             dest="name",
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/port-inspect.py b/snf-cyclades-app/synnefo/logic/management/commands/port-inspect.py
index ebd6bf6..a0897ae 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/port-inspect.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/port-inspect.py
@@ -32,17 +32,18 @@
 # or implied, of GRNET S.A.
 
 from optparse import make_option
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
 
+from snf_django.management.commands import SynnefoCommand
 from synnefo.management.common import convert_api_faults
 from synnefo.management import pprint, common
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     help = "Inspect a port on DB and Ganeti"
     args = "<port ID>"
 
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option(
             '--jobs',
             action='store_true',
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/queue-inspect.py b/snf-cyclades-app/synnefo/logic/management/commands/queue-inspect.py
index a976c0f..8d2836a 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/queue-inspect.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/queue-inspect.py
@@ -31,17 +31,18 @@
 import pprint
 
 from optparse import make_option
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
 
 from synnefo.lib.amqp import AMQPClient
+from snf_django.management.commands import SynnefoCommand
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     args = "<queue name>"
     help = "Inspect the messages of a queue. Close all other clients in "\
            "order to be able to inspect unacknowledged messages."
 
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option('--no-requeue', action='store_false', dest='requeue',
                     default=True, help="Do not requeue the messages"),
         make_option('-i', '--interactive', action='store_true', default=False,
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/queue-retry.py b/snf-cyclades-app/synnefo/logic/management/commands/queue-retry.py
index 2a697e2..08a6bb0 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/queue-retry.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/queue-retry.py
@@ -27,10 +27,10 @@
 # those of the authors and should not be interpreted as representing official
 # policies, either expressed or implied, of GRNET S.A.
 #
-from django.core.management.base import BaseCommand
 from optparse import make_option
 
 from synnefo.lib.amqp import AMQPClient
+from snf_django.management.commands import SynnefoCommand
 
 from synnefo.logic import queues
 
@@ -39,10 +39,10 @@ import logging
 log = logging.getLogger("")
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     help = "Resend messages from dead letter queues to original exchange"""
 
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option(
             '--keep-zombies',
             action='store_true',
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/reconcile-networks.py b/snf-cyclades-app/synnefo/logic/management/commands/reconcile-networks.py
index e86d609..835f061 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/reconcile-networks.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/reconcile-networks.py
@@ -36,11 +36,12 @@ logic/reconciliation.py for a description of reconciliation rules.
 """
 import logging
 from optparse import make_option
-from django.core.management.base import BaseCommand
+
 from synnefo.logic import reconciliation
+from snf_django.management.commands import SynnefoCommand
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     help = """Reconcile contents of Synnefo DB with state of Ganeti backend
 
 Network reconciliation can detect and fix the following cases:
@@ -53,7 +54,7 @@ Network reconciliation can detect and fix the following cases:
 """
 
     can_import_settings = True
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option('--fix-all', action='store_true',
                     dest='fix', default=False,
                     help='Fix all issues.'),
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/reconcile-pools.py b/snf-cyclades-app/synnefo/logic/management/commands/reconcile-pools.py
index 5a15961..5c46a16 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/reconcile-pools.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/reconcile-pools.py
@@ -29,8 +29,9 @@
 #
 import logging
 from optparse import make_option
-from django.core.management.base import BaseCommand
+
 from synnefo.logic import reconciliation
+from snf_django.management.commands import SynnefoCommand
 
 
 HELP_MSG = """\
@@ -46,10 +47,10 @@ The pools for the following resources are checked:
     * Pool of IPv4 addresses for each network"""
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     help = HELP_MSG
 
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option("--fix", action="store_true",
                     dest="fix", default=False,
                     help='Fix all issues.'),
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/reconcile-servers.py b/snf-cyclades-app/synnefo/logic/management/commands/reconcile-servers.py
index db38ec9..97ecde3 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/reconcile-servers.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/reconcile-servers.py
@@ -38,17 +38,18 @@ import sys
 import logging
 import subprocess
 from optparse import make_option
-from django.core.management.base import BaseCommand
+
+from snf_django.management.commands import SynnefoCommand
 from synnefo.management.common import get_resource
 from synnefo.logic import reconciliation
 from snf_django.management.utils import parse_bool
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     can_import_settings = True
 
     help = 'Reconcile contents of Synnefo DB with state of Ganeti backend'
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option('--backend-id', default=None, dest='backend-id',
                     help='Reconcilie VMs only for this backend'),
         make_option("--parallel",
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/server-create.py b/snf-cyclades-app/synnefo/logic/management/commands/server-create.py
index b356035..fafb7e1 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/server-create.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/server-create.py
@@ -33,9 +33,11 @@
 
 from optparse import make_option
 
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
+
 from synnefo.management import common, pprint
 from snf_django.management.utils import parse_bool
+from snf_django.management.commands import SynnefoCommand
 
 from synnefo.logic import servers
 
@@ -47,10 +49,10 @@ backend-id.
 """
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     help = "Create a new VM." + HELP_MSG
 
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option("--backend-id", dest="backend_id",
                     help="Unique identifier of the Ganeti backend."
                          " Use snf-manage backend-list to find out"
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/server-import.py b/snf-cyclades-app/synnefo/logic/management/commands/server-import.py
index 8720575..264e6fc 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/server-import.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/server-import.py
@@ -33,12 +33,13 @@
 
 from optparse import make_option
 
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
 from synnefo.management import common
 
 from synnefo.db.models import VirtualMachine, Network, Flavor
 from synnefo.logic.utils import id_from_network_name, id_from_instance_name
 from synnefo.logic.backend import wait_for_job, connect_to_network
+from snf_django.management.commands import SynnefoCommand
 from synnefo.logic.rapi import GanetiApiError
 from synnefo.logic import servers
 from synnefo import quotas
@@ -58,12 +59,12 @@ connected to a public network of Synnefo.
 """
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     help = "Import an existing Ganeti VM into Synnefo." + HELP_MSG
     args = "<ganeti_instance_name>"
     output_transaction = True
 
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option(
             "--backend-id",
             dest="backend_id",
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/server-inspect.py b/snf-cyclades-app/synnefo/logic/management/commands/server-inspect.py
index d00b0d0..b1c8411 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/server-inspect.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/server-inspect.py
@@ -32,17 +32,18 @@
 # or implied, of GRNET S.A.
 
 from optparse import make_option
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
 
+from snf_django.management.commands import SynnefoCommand
 from synnefo.management import common
 from synnefo.management import pprint
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     help = "Inspect a server on DB and Ganeti"
     args = "<server ID>"
 
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option(
             '--jobs',
             action='store_true',
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/server-modify.py b/snf-cyclades-app/synnefo/logic/management/commands/server-modify.py
index 531fd4e..34efed2 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/server-modify.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/server-modify.py
@@ -34,9 +34,11 @@
 from optparse import make_option
 
 from django.db import transaction
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
+
 from synnefo.management.common import (get_resource, convert_api_faults,
                                        wait_server_task)
+from snf_django.management.commands import SynnefoCommand
 from snf_django.management.utils import parse_bool
 from synnefo.logic import servers
 
@@ -44,11 +46,11 @@ from synnefo.logic import servers
 ACTIONS = ["start", "stop", "reboot_hard", "reboot_soft"]
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     args = "<server ID>"
     help = "Modify a server."
 
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option(
             '--name',
             dest='name',
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/service-export-cyclades.py b/snf-cyclades-app/synnefo/logic/management/commands/service-export-cyclades.py
index 146f189..36698f7 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/service-export-cyclades.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/service-export-cyclades.py
@@ -32,12 +32,13 @@
 # or implied, of GRNET S.A.
 
 from django.utils import simplejson as json
-from django.core.management.base import NoArgsCommand
+
+from snf_django.management.commands import SynnefoCommand
 from synnefo.cyclades_settings import cyclades_services
 from synnefo.lib.services import filter_public
 
 
-class Command(NoArgsCommand):
+class Command(SynnefoCommand):
     help = "Export Cyclades services in JSON format."
 
     def handle(self, *args, **options):
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/subnet-create.py b/snf-cyclades-app/synnefo/logic/management/commands/subnet-create.py
index e12fded..fea20ee 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/subnet-create.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/subnet-create.py
@@ -33,8 +33,10 @@
 
 from optparse import make_option
 
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
+
 from synnefo.management import common
+from snf_django.management.commands import SynnefoCommand
 from snf_django.management.utils import parse_bool
 from synnefo.management import pprint
 from synnefo.logic import subnets
@@ -47,10 +49,10 @@ Network ID.
 """
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     help = "Create a new Subnet." + HELP_MSG
 
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option("--network-id", dest="network_id",
                     help="Specify the Network to attach the subnet. To get the"
                          " networks of a user, use snf-manage network-list"),
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/subnet-inspect.py b/snf-cyclades-app/synnefo/logic/management/commands/subnet-inspect.py
index b2f7a62..b45c93e 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/subnet-inspect.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/subnet-inspect.py
@@ -33,14 +33,16 @@
 
 #from optparse import make_option
 
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
+
+from snf_django.management.commands import SynnefoCommand
 from synnefo.management import pprint, common
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     help = "Inspect a subnet on DB and Ganeti."
     args = "<Subnet ID>"
-    option_list = BaseCommand.option_list
+    option_list = SynnefoCommand.option_list
 
     def handle(self, *args, **options):
         if len(args) != 1:
diff --git a/snf-cyclades-app/synnefo/logic/management/commands/subnet-modify.py b/snf-cyclades-app/synnefo/logic/management/commands/subnet-modify.py
index bbbd645..93b8adc 100644
--- a/snf-cyclades-app/synnefo/logic/management/commands/subnet-modify.py
+++ b/snf-cyclades-app/synnefo/logic/management/commands/subnet-modify.py
@@ -33,7 +33,9 @@
 
 from optparse import make_option
 
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
+
+from snf_django.management.commands import SynnefoCommand
 from synnefo.management import common
 
 from synnefo.logic import subnets
@@ -45,10 +47,10 @@ be updated.
 """
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     help = "Update a Subnet." + HELP_MSG
     args = "<Subnet ID>"
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option("--name", dest="name",
                     help="The new subnet name."),
     )
diff --git a/snf-cyclades-app/synnefo/plankton/management/commands/image-list.py b/snf-cyclades-app/synnefo/plankton/management/commands/image-list.py
index 01ea0f8..5d7c577 100644
--- a/snf-cyclades-app/synnefo/plankton/management/commands/image-list.py
+++ b/snf-cyclades-app/synnefo/plankton/management/commands/image-list.py
@@ -27,17 +27,16 @@
 # those of the authors and should not be interpreted as representing official
 # policies, either expressed or implied, of GRNET S.A.
 #
-
-from django.core.management.base import BaseCommand
 from optparse import make_option
 
+from snf_django.management.commands import SynnefoCommand
 from snf_django.management.utils import pprint_table
 from synnefo.plankton.backend import PlanktonBackend
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     help = "List public images or images available to a user."
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option(
             '--user-id',
             dest='userid',
diff --git a/snf-cyclades-app/synnefo/plankton/management/commands/image-show.py b/snf-cyclades-app/synnefo/plankton/management/commands/image-show.py
index 513dc10..77d9cb1 100644
--- a/snf-cyclades-app/synnefo/plankton/management/commands/image-show.py
+++ b/snf-cyclades-app/synnefo/plankton/management/commands/image-show.py
@@ -28,13 +28,14 @@
 # policies, either expressed or implied, of GRNET S.A.
 #
 
-from django.core.management.base import BaseCommand, CommandError
+from django.core.management.base import CommandError
 
+from snf_django.management.commands import SynnefoCommand
 from synnefo.plankton.backend import PlanktonBackend
 from snf_django.management import utils
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     args = "<image_id>"
     help = "Display available information about an image"
 
diff --git a/snf-cyclades-app/synnefo/quotas/management/commands/reconcile-commissions-cyclades.py b/snf-cyclades-app/synnefo/quotas/management/commands/reconcile-commissions-cyclades.py
index a18cefb..5017655 100644
--- a/snf-cyclades-app/synnefo/quotas/management/commands/reconcile-commissions-cyclades.py
+++ b/snf-cyclades-app/synnefo/quotas/management/commands/reconcile-commissions-cyclades.py
@@ -31,16 +31,16 @@
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.
 
-from django.core.management.base import BaseCommand
 from optparse import make_option
 
+from snf_django.management.commands import SynnefoCommand
 from synnefo import quotas
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     help = "Detect and resolve pending commissions to Quotaholder"
     output_transaction = True
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option("--fix", dest="fix",
                     action='store_true',
                     default=False,
diff --git a/snf-cyclades-app/synnefo/quotas/management/commands/reconcile-resources-cyclades.py b/snf-cyclades-app/synnefo/quotas/management/commands/reconcile-resources-cyclades.py
index 2a7d3c4..ef62617 100644
--- a/snf-cyclades-app/synnefo/quotas/management/commands/reconcile-resources-cyclades.py
+++ b/snf-cyclades-app/synnefo/quotas/management/commands/reconcile-resources-cyclades.py
@@ -32,23 +32,23 @@
 # or implied, of GRNET S.A.
 
 from datetime import datetime
-from django.core.management.base import BaseCommand
 from optparse import make_option
 
 from synnefo import quotas
 from synnefo.quotas import util
 from snf_django.management.utils import pprint_table
+from snf_django.management.commands import SynnefoCommand
 from snf_django.utils import reconcile
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     help = """Reconcile resource usage of Astakos with Cyclades DB.
 
     Detect unsynchronized usage between Astakos and Cyclades DB resources and
     synchronize them if specified so.
 
     """
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option("--userid", dest="userid",
                     default=None,
                     help="Reconcile resources only for this user"),
diff --git a/snf-pithos-app/pithos/api/management/commands/reconcile-commissions-pithos.py b/snf-pithos-app/pithos/api/management/commands/reconcile-commissions-pithos.py
index 1ad07ef..35819d2 100644
--- a/snf-pithos-app/pithos/api/management/commands/reconcile-commissions-pithos.py
+++ b/snf-pithos-app/pithos/api/management/commands/reconcile-commissions-pithos.py
@@ -31,10 +31,11 @@
 # interpreted as representing official policies, either expressed
 # or implied, of GRNET S.A.
 
-from django.core.management.base import NoArgsCommand, CommandError
+from django.core.management.base import CommandError
 from optparse import make_option
 
 from pithos.api.util import get_backend
+from snf_django.management.commands import SynnefoCommand
 
 import logging
 
@@ -43,10 +44,10 @@ logger = logging.getLogger(__name__)
 CLIENTKEY = 'pithos'
 
 
-class Command(NoArgsCommand):
+class Command(SynnefoCommand):
     help = "Display unresolved commissions and trigger their recovery"
 
-    option_list = NoArgsCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option('--fix',
                     dest='fix',
                     action="store_true",
diff --git a/snf-pithos-app/pithos/api/management/commands/reconcile-resources-pithos.py b/snf-pithos-app/pithos/api/management/commands/reconcile-resources-pithos.py
index 5ed724a..92cb213 100644
--- a/snf-pithos-app/pithos/api/management/commands/reconcile-resources-pithos.py
+++ b/snf-pithos-app/pithos/api/management/commands/reconcile-resources-pithos.py
@@ -32,7 +32,7 @@
 # or implied, of GRNET S.A.
 
 from datetime import datetime
-from django.core.management.base import NoArgsCommand, CommandError
+from django.core.management.base import CommandError
 
 from optparse import make_option
 
@@ -40,6 +40,7 @@ from pithos.api.util import get_backend
 
 from snf_django.management import utils
 
+from snf_django.management.commands import SynnefoCommand
 from astakosclient.errors import QuotaLimit, NotFound
 from snf_django.utils import reconcile
 
@@ -47,14 +48,14 @@ backend = get_backend()
 RESOURCES = ['pithos.diskspace']
 
 
-class Command(NoArgsCommand):
+class Command(SynnefoCommand):
     help = """Reconcile resource usage of Astakos with Pithos DB.
 
     Detect unsynchronized usage between Astakos and Pithos DB resources and
     synchronize them if specified so.
 
     """
-    option_list = NoArgsCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option("--userid", dest="userid",
                     default=None,
                     help="Reconcile resources only for this user"),
@@ -107,8 +108,8 @@ class Command(NoArgsCommand):
                                       db_usage, qh_result)
 
             unsynced_projects, projects_pending, projects_unknown =\
-            reconcile.check_projects(self.stderr, RESOURCES,
-                                     db_project_usage, qh_project_result)
+                reconcile.check_projects(self.stderr, RESOURCES,
+                                         db_project_usage, qh_project_result)
             pending_exists = users_pending or projects_pending
             unknown_exists = users_unknown or projects_unknown
 
diff --git a/snf-pithos-app/pithos/api/management/commands/service-export-pithos.py b/snf-pithos-app/pithos/api/management/commands/service-export-pithos.py
index 3028bf4..d8a7f32 100644
--- a/snf-pithos-app/pithos/api/management/commands/service-export-pithos.py
+++ b/snf-pithos-app/pithos/api/management/commands/service-export-pithos.py
@@ -32,12 +32,13 @@
 # or implied, of GRNET S.A.
 
 from django.utils import simplejson as json
-from django.core.management.base import NoArgsCommand
+
 from pithos.api.settings import pithos_services
 from synnefo.lib.services import filter_public
+from snf_django.management.commands import SynnefoCommand
 
 
-class Command(NoArgsCommand):
+class Command(SynnefoCommand):
     help = "Export Pithos services in JSON format."
 
     def handle(self, *args, **options):
diff --git a/snf-webproject/synnefo/webproject/management/commands/link_static.py b/snf-webproject/synnefo/webproject/management/commands/link_static.py
index eb023aa..db8f4d0 100644
--- a/snf-webproject/synnefo/webproject/management/commands/link_static.py
+++ b/snf-webproject/synnefo/webproject/management/commands/link_static.py
@@ -33,18 +33,18 @@ import os
 
 from django.utils.importlib import import_module
 from optparse import make_option
-
-from django.core.management.base import BaseCommand
 from django.conf import settings
 
+from snf_django.management.commands import SynnefoCommand
+
 STATIC_FILES = getattr(settings, "STATIC_FILES", {})
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
 
     help = 'Symlink static files to directory specified'
 
-    option_list = BaseCommand.option_list + (
+    option_list = SynnefoCommand.option_list + (
         make_option(
             '--static-root',
             action='store',
diff --git a/snf-webproject/synnefo/webproject/management/commands/show_urls.py b/snf-webproject/synnefo/webproject/management/commands/show_urls.py
index f7f310a..f3d76c9 100644
--- a/snf-webproject/synnefo/webproject/management/commands/show_urls.py
+++ b/snf-webproject/synnefo/webproject/management/commands/show_urls.py
@@ -2,10 +2,11 @@
 # http://code.google.com/p/django-command-extensions/
 
 from django.conf import settings
-from django.core.management.base import BaseCommand
 from django.core.management import color
 from django.utils import termcolors
 
+from snf_django.management.commands import SynnefoCommand
+
 
 def color_style():
     style = color.color_style()
@@ -26,7 +27,7 @@ except ImportError:
         extract_views_from_urlpatterns, simplify_regex
 
 
-class Command(BaseCommand):
+class Command(SynnefoCommand):
     help = "Displays all of the url matching routes for the project."
 
     requires_model_validation = True
