diff --git a/circle/circle/settings/production.py b/circle/circle/settings/production.py
index ab28f52..3221246 100644
--- a/circle/circle/settings/production.py
+++ b/circle/circle/settings/production.py
@@ -20,9 +20,12 @@
 
 
 from os import environ
+from sys import argv
 
 from base import *  # noqa
 
+if 'runserver' in argv:
+    SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTOCOL', 'https')
 
 ########## HOST CONFIGURATION
 # See: https://docs.djangoproject.com/en/1.5/releases/1.5/
diff --git a/circle/dashboard/admin.py b/circle/dashboard/admin.py
index 8f20a88..ac798ca 100644
--- a/circle/dashboard/admin.py
+++ b/circle/dashboard/admin.py
@@ -21,18 +21,22 @@ from django import contrib
 from django.contrib.auth.admin import UserAdmin, GroupAdmin
 from django.contrib.auth.models import User, Group
 
-from dashboard.models import Profile, GroupProfile
+from dashboard.models import Profile, GroupProfile, ConnectCommand
 
 
 class ProfileInline(contrib.admin.TabularInline):
     model = Profile
 
 
+class CommandInline(contrib.admin.TabularInline):
+    model = ConnectCommand
+
+
 class GroupProfileInline(contrib.admin.TabularInline):
     model = GroupProfile
 
 
-UserAdmin.inlines = (ProfileInline, )
+UserAdmin.inlines = (ProfileInline, CommandInline, )
 GroupAdmin.inlines = (GroupProfileInline, )
 
 contrib.admin.site.unregister(User)
diff --git a/circle/dashboard/forms.py b/circle/dashboard/forms.py
index cc3f504..c30ac45 100644
--- a/circle/dashboard/forms.py
+++ b/circle/dashboard/forms.py
@@ -54,7 +54,9 @@ from .models import Profile, GroupProfile
 from circle.settings.base import LANGUAGES, MAX_NODE_RAM
 from django.utils.translation import string_concat
 
-from .virtvalidator import domain_validator
+from .validators import domain_validator
+
+from dashboard.models import ConnectCommand
 
 LANGUAGES_WITH_CODE = ((l[0], string_concat(l[1], " (", l[0], ")"))
                        for l in LANGUAGES)
@@ -176,7 +178,14 @@ class GroupCreateForm(forms.ModelForm):
         self.fields['org_id'] = forms.ChoiceField(
             # TRANSLATORS: directory like in LDAP
             choices=choices, required=False, label=_('Directory identifier'))
-        if not new_groups:
+        if new_groups:
+            self.fields['org_id'].help_text = _(
+                "If you select an item here, the members of this directory "
+                "group will be automatically added to the group at the time "
+                "they log in. Please note that other users (those with "
+                "permissions like yours) may also automatically become a "
+                "group co-owner).")
+        else:
             self.fields['org_id'].widget = HiddenInput()
 
     def save(self, commit=True):
@@ -1057,6 +1066,22 @@ class UserKeyForm(forms.ModelForm):
         return super(UserKeyForm, self).clean()
 
 
+class ConnectCommandForm(forms.ModelForm):
+    class Meta:
+        fields = ('name', 'access_method', 'template')
+        model = ConnectCommand
+
+    def __init__(self, *args, **kwargs):
+        self.user = kwargs.pop("user")
+        super(ConnectCommandForm, self).__init__(*args, **kwargs)
+
+    def clean(self):
+        if self.user:
+            self.instance.user = self.user
+
+        return super(ConnectCommandForm, self).clean()
+
+
 class TraitsForm(forms.ModelForm):
 
     class Meta:
diff --git a/circle/dashboard/migrations/0015_auto__add_connectcommand.py b/circle/dashboard/migrations/0015_auto__add_connectcommand.py
new file mode 100644
index 0000000..9c01637
--- /dev/null
+++ b/circle/dashboard/migrations/0015_auto__add_connectcommand.py
@@ -0,0 +1,278 @@
+# -*- 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 'ConnectCommand'
+        db.create_table(u'dashboard_connectcommand', (
+            (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+            ('user', self.gf('django.db.models.fields.related.ForeignKey')(related_name='command_set', to=orm['auth.User'])),
+            ('access_method', self.gf('django.db.models.fields.CharField')(max_length=10)),
+            ('application', self.gf('django.db.models.fields.CharField')(max_length='128')),
+            ('template', self.gf('django.db.models.fields.CharField')(max_length=256, null=True, blank=True)),
+        ))
+        db.send_create_signal(u'dashboard', ['ConnectCommand'])
+
+
+    def backwards(self, orm):
+        # Deleting model 'ConnectCommand'
+        db.delete_table(u'dashboard_connectcommand')
+
+
+    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'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'dashboard.connectcommand': {
+            'Meta': {'object_name': 'ConnectCommand'},
+            'access_method': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
+            'application': ('django.db.models.fields.CharField', [], {'max_length': "'128'"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'template': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'command_set'", 'to': u"orm['auth.User']"})
+        },
+        u'dashboard.favourite': {
+            'Meta': {'object_name': 'Favourite'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'instance': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['vm.Instance']"}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"})
+        },
+        u'dashboard.futuremember': {
+            'Meta': {'unique_together': "(('org_id', 'group'),)", 'object_name': 'FutureMember'},
+            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.Group']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'org_id': ('django.db.models.fields.CharField', [], {'max_length': '64'})
+        },
+        u'dashboard.groupprofile': {
+            'Meta': {'object_name': 'GroupProfile'},
+            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'group': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['auth.Group']", 'unique': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'org_id': ('django.db.models.fields.CharField', [], {'max_length': '64', 'unique': 'True', 'null': 'True', 'blank': 'True'})
+        },
+        u'dashboard.notification': {
+            'Meta': {'ordering': "['-created']", 'object_name': 'Notification'},
+            'created': ('model_utils.fields.AutoCreatedField', [], {'default': 'datetime.datetime.now'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'message_data': ('jsonfield.fields.JSONField', [], {'null': 'True'}),
+            'modified': ('model_utils.fields.AutoLastModifiedField', [], {'default': 'datetime.datetime.now'}),
+            'status': ('model_utils.fields.StatusField', [], {'default': "'new'", 'max_length': '100', u'no_check_for_status': 'True'}),
+            'subject_data': ('jsonfield.fields.JSONField', [], {'null': 'True'}),
+            'to': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}),
+            'valid_until': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'})
+        },
+        u'dashboard.profile': {
+            'Meta': {'object_name': 'Profile'},
+            'disk_quota': ('sizefield.models.FileSizeField', [], {'default': '2147483648'}),
+            'email_notifications': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'instance_limit': ('django.db.models.fields.IntegerField', [], {'default': '5'}),
+            'org_id': ('django.db.models.fields.CharField', [], {'max_length': '64', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
+            'preferred_language': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '32'}),
+            'smb_password': ('django.db.models.fields.CharField', [], {'default': "u'uUmt7R9peX'", 'max_length': '20'}),
+            'use_gravatar': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'user': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['auth.User']", 'unique': 'True'})
+        },
+        u'firewall.domain': {
+            'Meta': {'object_name': 'Domain'},
+            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
+            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}),
+            'ttl': ('django.db.models.fields.IntegerField', [], {'default': '600'})
+        },
+        u'firewall.group': {
+            'Meta': {'object_name': 'Group'},
+            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}),
+            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'})
+        },
+        u'firewall.host': {
+            'Meta': {'ordering': "('normalized_hostname', 'vlan')", 'unique_together': "(('hostname', 'vlan'),)", 'object_name': 'Host'},
+            'comment': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'external_ipv4': ('firewall.fields.IPAddressField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['firewall.Group']", 'null': 'True', 'blank': 'True'}),
+            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ipv4': ('firewall.fields.IPAddressField', [], {'unique': 'True', 'max_length': '100'}),
+            'ipv6': ('firewall.fields.IPAddressField', [], {'max_length': '100', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
+            'location': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'mac': ('firewall.fields.MACAddressField', [], {'unique': 'True', 'max_length': '17'}),
+            'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'normalized_hostname': ('common.models.HumanSortField', [], {'default': "''", 'maximum_number_length': '4', 'max_length': '80', 'monitor': "'hostname'", 'blank': 'True'}),
+            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}),
+            'reverse': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}),
+            'shared_ip': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'vlan': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['firewall.Vlan']"})
+        },
+        u'firewall.vlan': {
+            'Meta': {'object_name': 'Vlan'},
+            'comment': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'dhcp_pool': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'domain': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['firewall.Domain']"}),
+            'host_ipv6_prefixlen': ('django.db.models.fields.IntegerField', [], {'default': '112'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ipv6_template': ('django.db.models.fields.TextField', [], {'default': "'2001:738:2001:4031:%(b)d:%(c)d:%(d)d:0'"}),
+            'managed': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}),
+            'network4': ('firewall.fields.IPNetworkField', [], {'max_length': '100'}),
+            'network6': ('firewall.fields.IPNetworkField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'network_type': ('django.db.models.fields.CharField', [], {'default': "'portforward'", 'max_length': '20'}),
+            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}),
+            'reverse_domain': ('django.db.models.fields.TextField', [], {'default': "'%(d)d.%(c)d.%(b)d.%(a)d.in-addr.arpa'"}),
+            'snat_ip': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39', 'null': 'True', 'blank': 'True'}),
+            'snat_to': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['firewall.Vlan']", 'null': 'True', 'blank': 'True'}),
+            'vid': ('django.db.models.fields.IntegerField', [], {'unique': 'True'})
+        },
+        u'storage.datastore': {
+            'Meta': {'ordering': "[u'name']", 'object_name': 'DataStore'},
+            'hostname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '40'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}),
+            'path': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '200'})
+        },
+        u'storage.disk': {
+            'Meta': {'ordering': "[u'name']", 'object_name': 'Disk'},
+            'base': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "u'derivatives'", 'null': 'True', 'to': u"orm['storage.Disk']"}),
+            'created': ('model_utils.fields.AutoCreatedField', [], {'default': 'datetime.datetime.now'}),
+            'datastore': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['storage.DataStore']"}),
+            'destroyed': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
+            'dev_num': ('django.db.models.fields.CharField', [], {'default': "u'a'", 'max_length': '1'}),
+            'filename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '256'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_ready': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'modified': ('model_utils.fields.AutoLastModifiedField', [], {'default': 'datetime.datetime.now'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
+            'size': ('sizefield.models.FileSizeField', [], {'default': 'None', 'null': 'True'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '10'})
+        },
+        u'vm.instance': {
+            'Meta': {'ordering': "(u'pk',)", 'object_name': 'Instance'},
+            'access_method': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
+            'active_since': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+            'arch': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
+            'boot_menu': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'created': ('model_utils.fields.AutoCreatedField', [], {'default': 'datetime.datetime.now'}),
+            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'destroyed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+            'disks': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "u'instance_set'", 'symmetrical': 'False', 'to': u"orm['storage.Disk']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_base': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'lease': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['vm.Lease']"}),
+            'max_ram_size': ('django.db.models.fields.IntegerField', [], {}),
+            'modified': ('model_utils.fields.AutoLastModifiedField', [], {'default': 'datetime.datetime.now'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
+            'node': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "u'instance_set'", 'null': 'True', 'to': u"orm['vm.Node']"}),
+            'num_cores': ('django.db.models.fields.IntegerField', [], {}),
+            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}),
+            'priority': ('django.db.models.fields.IntegerField', [], {}),
+            'pw': ('django.db.models.fields.CharField', [], {'max_length': '20'}),
+            'ram_size': ('django.db.models.fields.IntegerField', [], {}),
+            'raw_data': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'req_traits': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['vm.Trait']", 'symmetrical': 'False', 'blank': 'True'}),
+            'status': ('model_utils.fields.StatusField', [], {'default': "u'NOSTATE'", 'max_length': '100', u'no_check_for_status': 'True'}),
+            'status_changed': ('model_utils.fields.MonitorField', [], {'default': 'datetime.datetime.now', u'monitor': "u'status'"}),
+            'system': ('django.db.models.fields.TextField', [], {}),
+            'template': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "u'instance_set'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['vm.InstanceTemplate']"}),
+            'time_of_delete': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
+            'time_of_suspend': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
+            'vnc_port': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'unique': 'True', 'null': 'True', 'blank': 'True'})
+        },
+        u'vm.instancetemplate': {
+            'Meta': {'ordering': "(u'name',)", 'object_name': 'InstanceTemplate'},
+            'access_method': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
+            'arch': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
+            'boot_menu': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'created': ('model_utils.fields.AutoCreatedField', [], {'default': 'datetime.datetime.now'}),
+            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'disks': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "u'template_set'", 'symmetrical': 'False', 'to': u"orm['storage.Disk']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lease': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['vm.Lease']"}),
+            'max_ram_size': ('django.db.models.fields.IntegerField', [], {}),
+            'modified': ('model_utils.fields.AutoLastModifiedField', [], {'default': 'datetime.datetime.now'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'num_cores': ('django.db.models.fields.IntegerField', [], {}),
+            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['vm.InstanceTemplate']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
+            'priority': ('django.db.models.fields.IntegerField', [], {}),
+            'ram_size': ('django.db.models.fields.IntegerField', [], {}),
+            'raw_data': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'req_traits': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['vm.Trait']", 'symmetrical': 'False', 'blank': 'True'}),
+            'system': ('django.db.models.fields.TextField', [], {})
+        },
+        u'vm.lease': {
+            'Meta': {'ordering': "[u'name']", 'object_name': 'Lease'},
+            'delete_interval_seconds': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}),
+            'suspend_interval_seconds': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'})
+        },
+        u'vm.node': {
+            'Meta': {'ordering': "(u'-enabled', u'normalized_name')", 'object_name': 'Node'},
+            'created': ('model_utils.fields.AutoCreatedField', [], {'default': 'datetime.datetime.now'}),
+            'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'host': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['firewall.Host']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'modified': ('model_utils.fields.AutoLastModifiedField', [], {'default': 'datetime.datetime.now'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '50'}),
+            'normalized_name': ('common.models.HumanSortField', [], {'default': "''", 'maximum_number_length': '4', 'max_length': '100', 'monitor': "u'name'", 'blank': 'True'}),
+            'overcommit': ('django.db.models.fields.FloatField', [], {'default': '1.0'}),
+            'priority': ('django.db.models.fields.IntegerField', [], {}),
+            'traits': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['vm.Trait']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        u'vm.trait': {
+            'Meta': {'object_name': 'Trait'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['dashboard']
\ No newline at end of file
diff --git a/circle/dashboard/migrations/0016_auto__del_field_connectcommand_application__add_field_connectcommand_n.py b/circle/dashboard/migrations/0016_auto__del_field_connectcommand_application__add_field_connectcommand_n.py
new file mode 100644
index 0000000..d43b315
--- /dev/null
+++ b/circle/dashboard/migrations/0016_auto__del_field_connectcommand_application__add_field_connectcommand_n.py
@@ -0,0 +1,281 @@
+# -*- 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):
+        # Deleting field 'ConnectCommand.application'
+        db.delete_column(u'dashboard_connectcommand', 'application')
+
+        # Adding field 'ConnectCommand.name'
+        db.add_column(u'dashboard_connectcommand', 'name',
+                      self.gf('django.db.models.fields.CharField')(default='szia megint', max_length='128'),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Adding field 'ConnectCommand.application'
+        db.add_column(u'dashboard_connectcommand', 'application',
+                      self.gf('django.db.models.fields.CharField')(default='szia', max_length='128'),
+                      keep_default=False)
+
+        # Deleting field 'ConnectCommand.name'
+        db.delete_column(u'dashboard_connectcommand', 'name')
+
+
+    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'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'dashboard.connectcommand': {
+            'Meta': {'object_name': 'ConnectCommand'},
+            'access_method': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': "'128'"}),
+            'template': ('django.db.models.fields.CharField', [], {'max_length': '256', 'null': 'True', 'blank': 'True'}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'command_set'", 'to': u"orm['auth.User']"})
+        },
+        u'dashboard.favourite': {
+            'Meta': {'object_name': 'Favourite'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'instance': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['vm.Instance']"}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"})
+        },
+        u'dashboard.futuremember': {
+            'Meta': {'unique_together': "(('org_id', 'group'),)", 'object_name': 'FutureMember'},
+            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.Group']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'org_id': ('django.db.models.fields.CharField', [], {'max_length': '64'})
+        },
+        u'dashboard.groupprofile': {
+            'Meta': {'object_name': 'GroupProfile'},
+            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'group': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['auth.Group']", 'unique': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'org_id': ('django.db.models.fields.CharField', [], {'max_length': '64', 'unique': 'True', 'null': 'True', 'blank': 'True'})
+        },
+        u'dashboard.notification': {
+            'Meta': {'ordering': "['-created']", 'object_name': 'Notification'},
+            'created': ('model_utils.fields.AutoCreatedField', [], {'default': 'datetime.datetime.now'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'message_data': ('jsonfield.fields.JSONField', [], {'null': 'True'}),
+            'modified': ('model_utils.fields.AutoLastModifiedField', [], {'default': 'datetime.datetime.now'}),
+            'status': ('model_utils.fields.StatusField', [], {'default': "'new'", 'max_length': '100', u'no_check_for_status': 'True'}),
+            'subject_data': ('jsonfield.fields.JSONField', [], {'null': 'True'}),
+            'to': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}),
+            'valid_until': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'})
+        },
+        u'dashboard.profile': {
+            'Meta': {'object_name': 'Profile'},
+            'disk_quota': ('sizefield.models.FileSizeField', [], {'default': '2147483648'}),
+            'email_notifications': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'instance_limit': ('django.db.models.fields.IntegerField', [], {'default': '5'}),
+            'org_id': ('django.db.models.fields.CharField', [], {'max_length': '64', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
+            'preferred_language': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '32'}),
+            'smb_password': ('django.db.models.fields.CharField', [], {'default': "u'NRERukxe3Z'", 'max_length': '20'}),
+            'use_gravatar': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'user': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['auth.User']", 'unique': 'True'})
+        },
+        u'firewall.domain': {
+            'Meta': {'object_name': 'Domain'},
+            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
+            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}),
+            'ttl': ('django.db.models.fields.IntegerField', [], {'default': '600'})
+        },
+        u'firewall.group': {
+            'Meta': {'object_name': 'Group'},
+            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}),
+            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'})
+        },
+        u'firewall.host': {
+            'Meta': {'ordering': "('normalized_hostname', 'vlan')", 'unique_together': "(('hostname', 'vlan'),)", 'object_name': 'Host'},
+            'comment': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'external_ipv4': ('firewall.fields.IPAddressField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['firewall.Group']", 'null': 'True', 'blank': 'True'}),
+            'hostname': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ipv4': ('firewall.fields.IPAddressField', [], {'unique': 'True', 'max_length': '100'}),
+            'ipv6': ('firewall.fields.IPAddressField', [], {'max_length': '100', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
+            'location': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'mac': ('firewall.fields.MACAddressField', [], {'unique': 'True', 'max_length': '17'}),
+            'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'normalized_hostname': ('common.models.HumanSortField', [], {'default': "''", 'maximum_number_length': '4', 'max_length': '80', 'monitor': "'hostname'", 'blank': 'True'}),
+            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}),
+            'reverse': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}),
+            'shared_ip': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'vlan': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['firewall.Vlan']"})
+        },
+        u'firewall.vlan': {
+            'Meta': {'object_name': 'Vlan'},
+            'comment': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'dhcp_pool': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'domain': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['firewall.Domain']"}),
+            'host_ipv6_prefixlen': ('django.db.models.fields.IntegerField', [], {'default': '112'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'ipv6_template': ('django.db.models.fields.TextField', [], {'default': "'2001:738:2001:4031:%(b)d:%(c)d:%(d)d:0'"}),
+            'managed': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '20'}),
+            'network4': ('firewall.fields.IPNetworkField', [], {'max_length': '100'}),
+            'network6': ('firewall.fields.IPNetworkField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+            'network_type': ('django.db.models.fields.CharField', [], {'default': "'portforward'", 'max_length': '20'}),
+            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'null': 'True', 'blank': 'True'}),
+            'reverse_domain': ('django.db.models.fields.TextField', [], {'default': "'%(d)d.%(c)d.%(b)d.%(a)d.in-addr.arpa'"}),
+            'snat_ip': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39', 'null': 'True', 'blank': 'True'}),
+            'snat_to': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['firewall.Vlan']", 'null': 'True', 'blank': 'True'}),
+            'vid': ('django.db.models.fields.IntegerField', [], {'unique': 'True'})
+        },
+        u'storage.datastore': {
+            'Meta': {'ordering': "[u'name']", 'object_name': 'DataStore'},
+            'hostname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '40'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}),
+            'path': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '200'})
+        },
+        u'storage.disk': {
+            'Meta': {'ordering': "[u'name']", 'object_name': 'Disk'},
+            'base': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "u'derivatives'", 'null': 'True', 'to': u"orm['storage.Disk']"}),
+            'created': ('model_utils.fields.AutoCreatedField', [], {'default': 'datetime.datetime.now'}),
+            'datastore': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['storage.DataStore']"}),
+            'destroyed': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
+            'dev_num': ('django.db.models.fields.CharField', [], {'default': "u'a'", 'max_length': '1'}),
+            'filename': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '256'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_ready': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'modified': ('model_utils.fields.AutoLastModifiedField', [], {'default': 'datetime.datetime.now'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
+            'size': ('sizefield.models.FileSizeField', [], {'default': 'None', 'null': 'True'}),
+            'type': ('django.db.models.fields.CharField', [], {'max_length': '10'})
+        },
+        u'vm.instance': {
+            'Meta': {'ordering': "(u'pk',)", 'object_name': 'Instance'},
+            'access_method': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
+            'active_since': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+            'arch': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
+            'boot_menu': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'created': ('model_utils.fields.AutoCreatedField', [], {'default': 'datetime.datetime.now'}),
+            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'destroyed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+            'disks': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "u'instance_set'", 'symmetrical': 'False', 'to': u"orm['storage.Disk']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_base': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'lease': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['vm.Lease']"}),
+            'max_ram_size': ('django.db.models.fields.IntegerField', [], {}),
+            'modified': ('model_utils.fields.AutoLastModifiedField', [], {'default': 'datetime.datetime.now'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
+            'node': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "u'instance_set'", 'null': 'True', 'to': u"orm['vm.Node']"}),
+            'num_cores': ('django.db.models.fields.IntegerField', [], {}),
+            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}),
+            'priority': ('django.db.models.fields.IntegerField', [], {}),
+            'pw': ('django.db.models.fields.CharField', [], {'max_length': '20'}),
+            'ram_size': ('django.db.models.fields.IntegerField', [], {}),
+            'raw_data': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'req_traits': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['vm.Trait']", 'symmetrical': 'False', 'blank': 'True'}),
+            'status': ('model_utils.fields.StatusField', [], {'default': "u'NOSTATE'", 'max_length': '100', u'no_check_for_status': 'True'}),
+            'status_changed': ('model_utils.fields.MonitorField', [], {'default': 'datetime.datetime.now', u'monitor': "u'status'"}),
+            'system': ('django.db.models.fields.TextField', [], {}),
+            'template': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "u'instance_set'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': u"orm['vm.InstanceTemplate']"}),
+            'time_of_delete': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
+            'time_of_suspend': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
+            'vnc_port': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'unique': 'True', 'null': 'True', 'blank': 'True'})
+        },
+        u'vm.instancetemplate': {
+            'Meta': {'ordering': "(u'name',)", 'object_name': 'InstanceTemplate'},
+            'access_method': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
+            'arch': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
+            'boot_menu': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'created': ('model_utils.fields.AutoCreatedField', [], {'default': 'datetime.datetime.now'}),
+            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'disks': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "u'template_set'", 'symmetrical': 'False', 'to': u"orm['storage.Disk']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'lease': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['vm.Lease']"}),
+            'max_ram_size': ('django.db.models.fields.IntegerField', [], {}),
+            'modified': ('model_utils.fields.AutoLastModifiedField', [], {'default': 'datetime.datetime.now'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'num_cores': ('django.db.models.fields.IntegerField', [], {}),
+            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']"}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['vm.InstanceTemplate']", 'null': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True'}),
+            'priority': ('django.db.models.fields.IntegerField', [], {}),
+            'ram_size': ('django.db.models.fields.IntegerField', [], {}),
+            'raw_data': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'req_traits': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['vm.Trait']", 'symmetrical': 'False', 'blank': 'True'}),
+            'system': ('django.db.models.fields.TextField', [], {})
+        },
+        u'vm.lease': {
+            'Meta': {'ordering': "[u'name']", 'object_name': 'Lease'},
+            'delete_interval_seconds': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}),
+            'suspend_interval_seconds': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'})
+        },
+        u'vm.node': {
+            'Meta': {'ordering': "(u'-enabled', u'normalized_name')", 'object_name': 'Node'},
+            'created': ('model_utils.fields.AutoCreatedField', [], {'default': 'datetime.datetime.now'}),
+            'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'host': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['firewall.Host']"}),
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'modified': ('model_utils.fields.AutoLastModifiedField', [], {'default': 'datetime.datetime.now'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '50'}),
+            'normalized_name': ('common.models.HumanSortField', [], {'default': "''", 'maximum_number_length': '4', 'max_length': '100', 'monitor': "u'name'", 'blank': 'True'}),
+            'overcommit': ('django.db.models.fields.FloatField', [], {'default': '1.0'}),
+            'priority': ('django.db.models.fields.IntegerField', [], {}),
+            'traits': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['vm.Trait']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        u'vm.trait': {
+            'Meta': {'object_name': 'Trait'},
+            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        }
+    }
+
+    complete_apps = ['dashboard']
\ No newline at end of file
diff --git a/circle/dashboard/models.py b/circle/dashboard/models.py
index 044f0cd..5e9ec2f 100644
--- a/circle/dashboard/models.py
+++ b/circle/dashboard/models.py
@@ -46,8 +46,10 @@ from acl.models import AclBase
 from common.models import HumanReadableObject, create_readable, Encoder
 
 from vm.tasks.agent_tasks import add_keys, del_keys
+from vm.models.instance import ACCESS_METHODS
 
 from .store_api import Store, NoStoreException, NotOkException
+from .validators import connect_command_template_validator
 
 logger = getLogger(__name__)
 
@@ -100,6 +102,25 @@ class Notification(TimeStampedModel):
         self.message_data = None if value is None else value.to_dict()
 
 
+class ConnectCommand(Model):
+    user = ForeignKey(User, related_name='command_set')
+    access_method = CharField(max_length=10, choices=ACCESS_METHODS,
+                              verbose_name=_('access method'),
+                              help_text=_('Type of the remote access method.'))
+    name = CharField(max_length="128", verbose_name=_('name'), blank=False,
+                     help_text=_("Name of your custom command."))
+    template = CharField(blank=True, null=True, max_length=256,
+                         verbose_name=_('command template'),
+                         help_text=_('Template for connection command string. '
+                                     'Available parameters are: '
+                                     'username, password, '
+                                     'host, port.'),
+                         validators=[connect_command_template_validator])
+
+    def __unicode__(self):
+        return self.template
+
+
 class Profile(Model):
     user = OneToOneField(User)
     preferred_language = CharField(verbose_name=_('preferred language'),
@@ -129,6 +150,25 @@ class Profile(Model):
         default=2048 * 1024 * 1024,
         help_text=_('Disk quota in mebibytes.'))
 
+    def get_connect_commands(self, instance, use_ipv6=False):
+        """ Generate connection command based on template."""
+        single_command = instance.get_connect_command(use_ipv6)
+        if single_command:  # can we even connect to that VM
+            commands = self.user.command_set.filter(
+                access_method=instance.access_method)
+            if commands.count() < 1:
+                return [single_command]
+            else:
+                return [
+                    command.template % {
+                        'port': instance.get_connect_port(use_ipv6=use_ipv6),
+                        'host':  instance.get_connect_host(use_ipv6=use_ipv6),
+                        'password': instance.pw,
+                        'username': 'cloud',
+                    } for command in commands]
+        else:
+            return []
+
     def notify(self, subject, template, context=None, valid_until=None,
                **kwargs):
         if context is not None:
diff --git a/circle/dashboard/static/dashboard/dashboard.css b/circle/dashboard/static/dashboard/dashboard.css
index 489cad8..d33d8ce 100644
--- a/circle/dashboard/static/dashboard/dashboard.css
+++ b/circle/dashboard/static/dashboard/dashboard.css
@@ -654,7 +654,8 @@ textarea[name="list-new-namelist"] {
   width: 130px;
 }
 
-#vm-details-connection-string-copy {
+.vm-details-connection-string-copy,
+#vm-details-pw-show {
   cursor: pointer;
 }
 
@@ -681,10 +682,9 @@ textarea[name="list-new-namelist"] {
   max-width: 200px;
 }
 
-#dashboard-vm-details-connect-command {
+.dashboard-vm-details-connect-command {
   /* for mobile view */
   margin-bottom: 20px;
-
 }
 
 #store-list-list {
@@ -868,6 +868,12 @@ textarea[name="list-new-namelist"] {
   padding: 5px 0px;
 }
 
+#profile-key-list-table td:last-child, #profile-key-list-table th:last-child,
+#profile-command-list-table td:last-child, #profile-command-list-table th:last-child,
+#profile-command-list-table td:nth-child(2), #profile-command-list-table th:nth-child(2) {
+  text-align: center;
+  vertical-align: middle;
+}
 
 #vm-list-table .migrating-icon {
   -webkit-animation: passing 2s linear infinite;
diff --git a/circle/dashboard/static/dashboard/vm-details.js b/circle/dashboard/static/dashboard/vm-details.js
index 475e038..3312ad2 100644
--- a/circle/dashboard/static/dashboard/vm-details.js
+++ b/circle/dashboard/static/dashboard/vm-details.js
@@ -105,19 +105,20 @@ $(function() {
   $("#vm-details-pw-show").click(function() {
     var input = $(this).parent("div").children("input");
     var eye = $(this).children("#vm-details-pw-eye");
+    var span = $(this);
     
-    eye.tooltip("destroy")
+    span.tooltip("destroy")
     if(eye.hasClass("fa-eye")) {
       eye.removeClass("fa-eye").addClass("fa-eye-slash");
       input.prop("type", "text");
-      input.focus();
-      eye.prop("title", "Hide password");
+      input.select();
+      span.prop("title", gettext("Hide password"));
     } else {
       eye.removeClass("fa-eye-slash").addClass("fa-eye");
       input.prop("type", "password");
-      eye.prop("title", "Show password");
+      span.prop("title", gettext("Show password"));
     }
-    eye.tooltip();
+    span.tooltip();
   });
 
   /* change password confirmation */
@@ -198,7 +199,7 @@ $(function() {
   $("#vm-details-h1-name, .vm-details-rename-button").click(function() {
     $("#vm-details-h1-name").hide();
     $("#vm-details-rename").css('display', 'inline');
-    $("#vm-details-rename-name").focus();
+    $("#vm-details-rename-name").select();
     return false;
   });
 
@@ -206,7 +207,7 @@ $(function() {
   $(".vm-details-home-edit-name-click").click(function() {
     $(".vm-details-home-edit-name-click").hide();
     $("#vm-details-home-rename").show();
-    $("input", $("#vm-details-home-rename")).focus();
+    $("input", $("#vm-details-home-rename")).select();
     return false;
   });
 
@@ -306,8 +307,8 @@ $(function() {
   });
 
   // select connection string
-  $("#vm-details-connection-string-copy").click(function() {
-    $("#vm-details-connection-string").focus();
+  $(".vm-details-connection-string-copy").click(function() {
+    $(this).parent("div").find("input").select();
   });
 
   $("a.operation-password_reset").click(function() {
diff --git a/circle/dashboard/tables.py b/circle/dashboard/tables.py
index 88e9c8f..e078a4a 100644
--- a/circle/dashboard/tables.py
+++ b/circle/dashboard/tables.py
@@ -25,6 +25,7 @@ from django_tables2.columns import (TemplateColumn, Column, BooleanColumn,
 from vm.models import Node, InstanceTemplate, Lease
 from django.utils.translation import ugettext_lazy as _
 from django_sshkey.models import UserKey
+from dashboard.models import ConnectCommand
 
 
 class NodeListTable(Table):
@@ -249,5 +250,41 @@ class UserKeyListTable(Table):
 
     class Meta:
         model = UserKey
-        attrs = {'class': ('table table-bordered table-striped table-hover')}
+        attrs = {'class': ('table table-bordered table-striped table-hover'),
+                 'id': "profile-key-list-table"}
         fields = ('name', 'fingerprint', 'created', 'actions')
+        prefix = "key-"
+        empty_text = _("You haven't added any public keys yet.")
+
+
+class ConnectCommandListTable(Table):
+    name = LinkColumn(
+        'dashboard.views.connect-command-detail',
+        args=[A('pk')],
+        attrs={'th': {'data-sort': "string"}}
+    )
+    access_method = Column(
+        verbose_name=_("Access method"),
+        attrs={'th': {'data-sort': "string"}}
+    )
+    template = Column(
+        verbose_name=_("Template"),
+        attrs={'th': {'data-sort': "string"}}
+    )
+    actions = TemplateColumn(
+        verbose_name=_("Actions"),
+        template_name=("dashboard/connect-command-list/column-command"
+                       "-actions.html"),
+        orderable=False,
+    )
+
+    class Meta:
+        model = ConnectCommand
+        attrs = {'class': ('table table-bordered table-striped table-hover'),
+                 'id': "profile-command-list-table"}
+        fields = ('name', 'access_method',  'template', 'actions')
+        prefix = "cmd-"
+        empty_text = _(
+            "You don't have any custom connection commands yet. You can "
+            "specify commands to be displayed on VM detail pages instead of "
+            "the defaults.")
diff --git a/circle/dashboard/templates/dashboard/connect-command-create.html b/circle/dashboard/templates/dashboard/connect-command-create.html
new file mode 100644
index 0000000..ebbb883
--- /dev/null
+++ b/circle/dashboard/templates/dashboard/connect-command-create.html
@@ -0,0 +1,44 @@
+{% extends "dashboard/base.html" %}
+{% load i18n %}
+{% load crispy_forms_tags %}
+
+{% block title-page %}{% trans "Create command template" %}{% endblock %}
+
+{% block content %}
+
+<div class="row">
+  <div class="col-md-12">
+    <div class="panel panel-default">
+      <div class="panel-heading">
+        <a class="pull-right btn btn-default btn-xs" href="{% url "dashboard.views.profile-preferences" %}">{% trans "Back" %}</a>
+        <h3 class="no-margin"><i class="fa fa-code"></i> {% trans "Create new command template" %}</h3>
+      </div>
+      <div class="panel-body">
+        <form method="POST">
+          {% csrf_token %}
+          {{ form.name|as_crispy_field }}
+          {{ form.access_method|as_crispy_field }}
+          {{ form.template|as_crispy_field }}
+          <p class="text-muted">
+            {% trans "Examples" %}
+          </p>
+          <p>
+            <strong>SSH:</strong>
+            <span class="text-muted">
+              sshpass -p %(password)s ssh -o StrictHostKeyChecking=no cloud@%(host)s -p %(port)d
+            </span>
+          </p>
+          <p>
+            <strong>RDP:</strong>
+            <span class="text-muted">
+              rdesktop %(host)s:%(port)d -u cloud -p %(password)s
+            </span>
+          </p>
+          <input type="submit" class="btn btn-primary" value="{% trans "Save" %}">
+        </form>
+      </div>
+    </div>
+  </div>
+</div>
+
+{% endblock %}
diff --git a/circle/dashboard/templates/dashboard/connect-command-edit.html b/circle/dashboard/templates/dashboard/connect-command-edit.html
new file mode 100644
index 0000000..25c014d
--- /dev/null
+++ b/circle/dashboard/templates/dashboard/connect-command-edit.html
@@ -0,0 +1,44 @@
+{% extends "dashboard/base.html" %}
+{% load i18n %}
+{% load crispy_forms_tags %}
+
+{% block title-page %}{% trans "Edit command template" %}{% endblock %}
+
+{% block content %}
+
+<div class="row">
+  <div class="col-md-12">
+    <div class="panel panel-default">
+      <div class="panel-heading">
+        <a class="pull-right btn btn-default btn-xs" href="{% url "dashboard.views.profile-preferences" %}">{% trans "Back" %}</a>
+        <h3 class="no-margin"><i class="fa fa-code"></i> {% trans "Edit command template" %}</h3>
+      </div>
+      <div class="panel-body">
+        <form method="POST">
+          {% csrf_token %}
+          {{ form.name|as_crispy_field }}
+          {{ form.access_method|as_crispy_field }}
+          {{ form.template|as_crispy_field }}
+          <p class="text-muted">
+            {% trans "Examples" %}
+          </p>
+          <p>
+            <strong>SSH:</strong>
+            <span class="text-muted">
+              sshpass -p %(password)s ssh -o StrictHostKeyChecking=no cloud@%(host)s -p %(port)d
+            </span>
+          </p>
+          <p>
+            <strong>RDP:</strong>
+            <span class="text-muted">
+              rdesktop %(host)s:%(port)d -u cloud -p %(password)s
+            </span>
+          </p>
+          <input type="submit" class="btn btn-primary" value="{% trans "Save" %}">
+        </form>
+      </div>
+    </div>
+  </div>
+</div>
+
+{% endblock %}
diff --git a/circle/dashboard/templates/dashboard/connect-command-list/column-command-actions.html b/circle/dashboard/templates/dashboard/connect-command-list/column-command-actions.html
new file mode 100644
index 0000000..8ed8cb6
--- /dev/null
+++ b/circle/dashboard/templates/dashboard/connect-command-list/column-command-actions.html
@@ -0,0 +1,7 @@
+{% load i18n %}
+<a href="{% url "dashboard.views.connect-command-detail" pk=record.pk%}" id="template-list-edit-button" class="btn btn-default btn-xs" title="{% trans "Edit" %}">
+  <i class="fa fa-edit"></i>
+</a>
+<a data-template-pk="{{ record.pk }}" href="{% url "dashboard.views.connect-command-delete" pk=record.pk %}" class="btn btn-danger btn-xs template-delete" title="{% trans "Delete" %}">
+  <i class="fa fa-times"></i>
+</a>
diff --git a/circle/dashboard/templates/dashboard/group-create.html b/circle/dashboard/templates/dashboard/group-create.html
index 35e47a9..1574e36 100644
--- a/circle/dashboard/templates/dashboard/group-create.html
+++ b/circle/dashboard/templates/dashboard/group-create.html
@@ -1,4 +1,10 @@
 {% load crispy_forms_tags %}
+{% load i18n %}
+
+<p class="text-muted">
+{% trans "User groups allow sharing templates or other resources with multiple users at once." %}
+</p>
+
 
 <form method="POST" action="{% url "dashboard.views.group-create" %}">
 {% csrf_token %}
diff --git a/circle/dashboard/templates/dashboard/profile_form.html b/circle/dashboard/templates/dashboard/profile_form.html
index beb4b47..4f3a543 100644
--- a/circle/dashboard/templates/dashboard/profile_form.html
+++ b/circle/dashboard/templates/dashboard/profile_form.html
@@ -66,4 +66,20 @@
   </div>
 </div>
 
+<div class="row">
+  <div class="col-md-12">
+    <div class="panel panel-default">
+      <div class="panel-heading">
+        <a href="{% url "dashboard.views.connect-command-create" %}"
+          class="pull-right btn btn-success btn-xs" style="margin-right: 10px;">
+          <i class="fa fa-plus"></i> {% trans "add command template" %}
+        </a>
+        <h3 class="no-margin"><i class="fa fa-code"></i> {% trans "Command templates" %}</h3>
+      </div>
+      <div class="panel-body">
+        {% render_table connectcommand_table %}
+      </div>
+    </div>
+  </div>
+</div>
 {% endblock %}
diff --git a/circle/dashboard/templates/dashboard/vm-detail.html b/circle/dashboard/templates/dashboard/vm-detail.html
index 43f747a..6131a59 100644
--- a/circle/dashboard/templates/dashboard/vm-detail.html
+++ b/circle/dashboard/templates/dashboard/vm-detail.html
@@ -98,8 +98,9 @@
           <div class="input-group">
             <input type="text" id="vm-details-pw-input" class="form-control input-sm input-tags"
             value="{{ instance.pw }}" spellcheck="false"/>
-            <span class="input-group-addon input-tags" id="vm-details-pw-show">
-              <i class="fa fa-eye" id="vm-details-pw-eye" title="Show password"></i>
+            <span class="input-group-addon input-tags" id="vm-details-pw-show"
+              title="{% trans "Show password" %}" data-container="body">
+              <i class="fa fa-eye" id="vm-details-pw-eye"></i>
             </span>
           </div>
         </dd>
@@ -111,16 +112,29 @@
           </div>
         </dd>
       </dl>
-
-      <div class="input-group" id="dashboard-vm-details-connect-command">
+      {% for c in connect_commands %}
+      <div class="input-group dashboard-vm-details-connect-command">
         <span class="input-group-addon input-tags">{% trans "Command" %}</span>
         <input type="text" spellcheck="false"
-        value="{% if instance.get_connect_command %}{{ instance.get_connect_command }}{% else %}{% trans "Connection is not possible." %}{% endif %}"
+        value="{{ c }}"
+        id="vm-details-connection-string" class="form-control input-tags" />
+        <span class="input-group-addon input-tags vm-details-connection-string-copy"
+          title="{% trans "Select all" %}" data-container="body">
+          <i class="fa fa-copy"></i>
+        </span>
+      </div>
+
+      {% empty %}
+      <div class="input-group dashboard-vm-details-connect-command">
+        <span class="input-group-addon input-tags">{% trans "Command" %}</span>
+        <input type="text" spellcheck="false" value="{% trans "Connection is not possible." %}"
         id="vm-details-connection-string" class="form-control input-tags" />
         <span class="input-group-addon input-tags" id="vm-details-connection-string-copy">
           <i class="fa fa-copy" title="{% trans "Select all" %}"></i>
         </span>
       </div>
+
+      {% endfor %}
     </div>
     <div class="col-md-8" id="vm-detail-pane">
       <div class="panel panel-default" id="vm-detail-panel">
diff --git a/circle/dashboard/templates/dashboard/vm-detail/home.html b/circle/dashboard/templates/dashboard/vm-detail/home.html
index 1ec326f..4c946bf 100644
--- a/circle/dashboard/templates/dashboard/vm-detail/home.html
+++ b/circle/dashboard/templates/dashboard/vm-detail/home.html
@@ -94,7 +94,13 @@
       <dt>{% trans "Template" %}:</dt>
       <dd>
         {% if instance.template %}
-          {{ instance.template.name }}
+          {% if can_link_template %}
+          <a href="{{ instance.template.get_absolute_url }}">
+            {{ instance.template.name }}
+          </a>
+          {% else %}
+            {{ instance.template.name }}
+          {% endif %}
         {% else %}
           -
         {% endif %}
diff --git a/circle/dashboard/urls.py b/circle/dashboard/urls.py
index 6c7113b..00f5f69 100644
--- a/circle/dashboard/urls.py
+++ b/circle/dashboard/urls.py
@@ -39,6 +39,7 @@ from .views import (
     get_vm_screenshot,
     ProfileView, toggle_use_gravatar, UnsubscribeFormView,
     UserKeyDelete, UserKeyDetail, UserKeyCreate,
+    ConnectCommandDelete, ConnectCommandDetail, ConnectCommandCreate,
     StoreList, store_download, store_upload, store_get_upload_url, StoreRemove,
     store_new_directory, store_refresh_toplist,
     VmTraitsUpdate, VmRawDataUpdate,
@@ -177,6 +178,16 @@ urlpatterns = patterns(
         UserKeyCreate.as_view(),
         name="dashboard.views.userkey-create"),
 
+    url(r'^conncmd/delete/(?P<pk>\d+)/$',
+        ConnectCommandDelete.as_view(),
+        name="dashboard.views.connect-command-delete"),
+    url(r'^conncmd/(?P<pk>\d+)/$',
+        ConnectCommandDetail.as_view(),
+        name="dashboard.views.connect-command-detail"),
+    url(r'^conncmd/create/$',
+        ConnectCommandCreate.as_view(),
+        name="dashboard.views.connect-command-create"),
+
     url(r'^autocomplete/', include('autocomplete_light.urls')),
 
     url(r"^store/list/$", StoreList.as_view(),
diff --git a/circle/dashboard/virtvalidator.py b/circle/dashboard/validators.py
similarity index 71%
rename from circle/dashboard/virtvalidator.py
rename to circle/dashboard/validators.py
index fa68f99..c0acc9a 100644
--- a/circle/dashboard/virtvalidator.py
+++ b/circle/dashboard/validators.py
@@ -1,4 +1,6 @@
 from django.core.exceptions import ValidationError
+from django.utils.translation import ugettext_lazy as _
+
 from lxml import etree as ET
 import logging
 
@@ -29,3 +31,27 @@ def domain_validator(value):
             relaxng.assertValid(parsed_xml)
         except Exception as e:
             raise ValidationError(e.message)
+
+
+def connect_command_template_validator(value):
+    """Validate value as a connect command template.
+
+    >>> try: connect_command_template_validator("%(host)s")
+    ... except ValidationError as e: print e
+    ...
+    >>> connect_command_template_validator("%(host)s")
+    >>> try: connect_command_template_validator("%(host)s %s")
+    ... except ValidationError as e: print e
+    ...
+    [u'Invalid template string.']
+    """
+
+    try:
+        value % {
+            'username': "uname",
+            'password': "pw",
+            'host': "111.111.111.111",
+            'port': 12345,
+        }
+    except (KeyError, TypeError, ValueError):
+        raise ValidationError(_("Invalid template string."))
diff --git a/circle/dashboard/views.py b/circle/dashboard/views.py
index ba3304f..949e3ad 100644
--- a/circle/dashboard/views.py
+++ b/circle/dashboard/views.py
@@ -71,12 +71,12 @@ from .forms import (
     CirclePasswordChangeForm, VmCreateDiskForm, VmDownloadDiskForm,
     TraitsForm, RawDataForm, GroupPermissionForm, AclUserAddForm,
     VmResourcesForm, VmAddInterfaceForm, VmListSearchForm,
-    TemplateListSearchForm,
+    TemplateListSearchForm, ConnectCommandForm
 )
 
 from .tables import (
     NodeListTable, TemplateListTable, LeaseListTable,
-    GroupListTable, UserKeyListTable
+    GroupListTable, UserKeyListTable, ConnectCommandListTable,
 )
 from common.models import (
     HumanReadableObject, HumanReadableException, fetch_human_exception,
@@ -88,7 +88,8 @@ from vm.models import (
 )
 from storage.models import Disk
 from firewall.models import Vlan, Host, Rule
-from .models import Favourite, Profile, GroupProfile, FutureMember
+from .models import (Favourite, Profile, GroupProfile, FutureMember,
+                     ConnectCommand)
 
 from .store_api import Store, NoStoreException, NotOkException
 
@@ -366,6 +367,7 @@ class VmDetailView(CheckedDetailView):
                                     kwargs={'pk': self.object.pk}),
             'ops': ops,
             'op': {i.op: i for i in ops},
+            'connect_commands': user.profile.get_connect_commands(instance)
         })
 
         # activity data
@@ -396,7 +398,7 @@ class VmDetailView(CheckedDetailView):
 
         # resources forms
         can_edit = (
-            instance in Instance.get_objects_with_level("owner", user)
+            instance.has_level(user, "owner")
             and self.request.user.has_perm("vm.change_resources"))
         context['resources_form'] = VmResourcesForm(
             can_edit=can_edit, instance=instance)
@@ -409,6 +411,11 @@ class VmDetailView(CheckedDetailView):
         context['can_change_resources'] = self.request.user.has_perm(
             "vm.change_resources")
 
+        # can link template
+        context['can_link_template'] = (
+            instance.template and instance.template.has_level(user, "operator")
+        )
+
         return context
 
     def post(self, request, *args, **kwargs):
@@ -1538,7 +1545,7 @@ class TemplateChoose(LoginRequiredMixin, TemplateView):
                                                             self.request.user)
         context.update({
             'box_title': _('Choose template'),
-            'ajax_title': False,
+            'ajax_title': True,
             'template': "dashboard/_template-choose.html",
             'templates': templates.all(),
         })
@@ -2093,7 +2100,7 @@ class VmCreate(LoginRequiredMixin, TemplateView):
             context.update({
                 'template': 'dashboard/_vm-create-2.html',
                 'box_title': _('Customize VM'),
-                'ajax_title': False,
+                'ajax_title': True,
                 'vm_create_form': form,
                 'template_o': templates.get(pk=template),
             })
@@ -2101,7 +2108,7 @@ class VmCreate(LoginRequiredMixin, TemplateView):
             context.update({
                 'template': 'dashboard/_vm-create-1.html',
                 'box_title': _('Create a VM'),
-                'ajax_title': False,
+                'ajax_title': True,
                 'templates': templates.all(),
             })
         return self.render_to_response(context)
@@ -2291,9 +2298,9 @@ class GroupCreate(GroupCodeMixin, LoginRequiredMixin, TemplateView):
         context = self.get_context_data(**kwargs)
         context.update({
             'template': 'dashboard/group-create.html',
-            'box_title': 'Create a Group',
+            'box_title': _('Create a Group'),
             'form': form,
-
+            'ajax_title': True,
         })
         return self.render_to_response(context)
 
@@ -2961,11 +2968,16 @@ class MyPreferencesView(UpdateView):
                 user=self.request.user),
             'change_language': MyProfileForm(instance=self.get_object()),
         }
-        table = UserKeyListTable(
+        key_table = UserKeyListTable(
             UserKey.objects.filter(user=self.request.user),
             request=self.request)
-        table.page = None
-        context['userkey_table'] = table
+        key_table.page = None
+        context['userkey_table'] = key_table
+        cmd_table = ConnectCommandListTable(
+            self.request.user.command_set.all(),
+            request=self.request)
+        cmd_table.page = None
+        context['connectcommand_table'] = cmd_table
         return context
 
     def get_object(self, queryset=None):
@@ -3370,6 +3382,82 @@ class UserKeyCreate(LoginRequiredMixin, SuccessMessageMixin, CreateView):
         return kwargs
 
 
+class ConnectCommandDetail(LoginRequiredMixin, SuccessMessageMixin,
+                           UpdateView):
+    model = ConnectCommand
+    template_name = "dashboard/connect-command-edit.html"
+    form_class = ConnectCommandForm
+    success_message = _("Successfully modified command template.")
+
+    def get(self, request, *args, **kwargs):
+        object = self.get_object()
+        if object.user != request.user:
+            raise PermissionDenied()
+        return super(ConnectCommandDetail, self).get(request, *args, **kwargs)
+
+    def get_success_url(self):
+        return reverse_lazy("dashboard.views.connect-command-detail",
+                            kwargs=self.kwargs)
+
+    def post(self, request, *args, **kwargs):
+        object = self.get_object()
+        if object.user != request.user:
+            raise PermissionDenied()
+        return super(ConnectCommandDetail, self).post(request, args, kwargs)
+
+    def get_form_kwargs(self):
+        kwargs = super(ConnectCommandDetail, self).get_form_kwargs()
+        kwargs['user'] = self.request.user
+        return kwargs
+
+
+class ConnectCommandDelete(LoginRequiredMixin, DeleteView):
+    model = ConnectCommand
+
+    def get_success_url(self):
+        return reverse("dashboard.views.profile-preferences")
+
+    def get_template_names(self):
+        if self.request.is_ajax():
+            return ['dashboard/confirm/ajax-delete.html']
+        else:
+            return ['dashboard/confirm/base-delete.html']
+
+    def delete(self, request, *args, **kwargs):
+        object = self.get_object()
+        if object.user != request.user:
+            raise PermissionDenied()
+
+        object.delete()
+        success_url = self.get_success_url()
+        success_message = _("Command template successfully deleted.")
+
+        if request.is_ajax():
+            return HttpResponse(
+                json.dumps({'message': success_message}),
+                content_type="application/json",
+            )
+        else:
+            messages.success(request, success_message)
+            return HttpResponseRedirect(success_url)
+
+
+class ConnectCommandCreate(LoginRequiredMixin, SuccessMessageMixin,
+                           CreateView):
+    model = ConnectCommand
+    form_class = ConnectCommandForm
+    template_name = "dashboard/connect-command-create.html"
+    success_message = _("Successfully created a new command template.")
+
+    def get_success_url(self):
+        return reverse_lazy("dashboard.views.profile-preferences")
+
+    def get_form_kwargs(self):
+        kwargs = super(ConnectCommandCreate, self).get_form_kwargs()
+        kwargs['user'] = self.request.user
+        return kwargs
+
+
 class HelpView(TemplateView):
 
     def get_context_data(self, *args, **kwargs):
diff --git a/circle/fabfile.py b/circle/fabfile.py
index b41813a..88244a7 100755
--- a/circle/fabfile.py
+++ b/circle/fabfile.py
@@ -101,7 +101,7 @@ def pull(dir="~/circle/circle"):
 @roles('portal')
 def update_portal(test=False):
     "Update and restart portal+manager"
-    with _stopped("portal", "mancelery"):
+    with _stopped("portal", "manager"):
         pull()
         pip("circle", "~/circle/requirements.txt")
         migrate()
@@ -113,7 +113,7 @@ def update_portal(test=False):
 @roles('portal')
 def stop_portal(test=False):
     "Stop portal and manager"
-    _stop_services("portal", "mancelery")
+    _stop_services("portal", "manager")
 
 
 @roles('node')
diff --git a/circle/firewall/models.py b/circle/firewall/models.py
index 5081059..882ba3f 100644
--- a/circle/firewall/models.py
+++ b/circle/firewall/models.py
@@ -215,7 +215,7 @@ class Rule(models.Model):
         dst = None
 
         if host:
-            ip = (host.ipv4, host.ipv6_with_prefixlen)
+            ip = (host.ipv4, host.ipv6_with_host_prefixlen)
             if self.direction == 'in':
                 dst = ip
             else:
@@ -530,14 +530,30 @@ class Host(models.Model):
     def incoming_rules(self):
         return self.rules.filter(direction='in')
 
-    @property
-    def ipv6_with_prefixlen(self):
+    @staticmethod
+    def create_ipnetwork(ip, prefixlen):
         try:
-            net = IPNetwork(self.ipv6)
-            net.prefixlen = self.vlan.host_ipv6_prefixlen
-            return net
+            net = IPNetwork(ip)
+            net.prefixlen = prefixlen
         except TypeError:
             return None
+        else:
+            return net
+
+    @property
+    def ipv4_with_vlan_prefixlen(self):
+        return Host.create_ipnetwork(
+            self.ipv4, self.vlan.network4.prefixlen)
+
+    @property
+    def ipv6_with_vlan_prefixlen(self):
+        return Host.create_ipnetwork(
+            self.ipv6, self.vlan.network6.prefixlen)
+
+    @property
+    def ipv6_with_host_prefixlen(self):
+        return Host.create_ipnetwork(
+            self.ipv6, self.vlan.host_ipv6_prefixlen)
 
     def get_external_ipv4(self):
         return self.external_ipv4 if self.external_ipv4 else self.ipv4
@@ -600,6 +616,19 @@ class Host(models.Model):
                        description='created by host.save()',
                        type='AAAA').save()
 
+    def get_network_config(self):
+        interface = {'addresses': []}
+
+        if self.ipv4 and self.vlan.network4:
+            interface['addresses'].append(str(self.ipv4_with_vlan_prefixlen))
+            interface['gw4'] = str(self.vlan.network4.ip)
+
+        if self.ipv6 and self.vlan.network6:
+            interface['addresses'].append(str(self.ipv6_with_vlan_prefixlen))
+            interface['gw6'] = str(self.vlan.network6.ip)
+
+        return interface
+
     def enable_net(self):
         for i in settings.get('default_host_groups', []):
             self.groups.add(Group.objects.get(name=i))
diff --git a/circle/manager/mancelery.py b/circle/manager/mancelery.py
index 71e01e6..3268fd9 100755
--- a/circle/manager/mancelery.py
+++ b/circle/manager/mancelery.py
@@ -31,7 +31,6 @@ celery = Celery('manager',
                          'storage.tasks.local_tasks',
                          'storage.tasks.periodic_tasks',
                          'firewall.tasks.local_tasks',
-                         'monitor.tasks.local_periodic_tasks',
                          'dashboard.tasks.local_periodic_tasks',
                          ])
 
@@ -42,20 +41,8 @@ celery.conf.update(
     CELERY_QUEUES=(
         Queue(HOSTNAME + '.man', Exchange('manager', type='direct'),
               routing_key="manager"),
-        Queue(HOSTNAME + '.monitor', Exchange('monitor', type='direct'),
-              routing_key="monitor"),
     ),
     CELERYBEAT_SCHEDULE={
-        'vm.update_domain_states': {
-            'task': 'vm.tasks.local_periodic_tasks.update_domain_states',
-            'schedule': timedelta(seconds=10),
-            'options': {'queue': 'localhost.man'}
-        },
-        'vm.garbage_collector': {
-            'task': 'vm.tasks.local_periodic_tasks.garbage_collector',
-            'schedule': timedelta(minutes=10),
-            'options': {'queue': 'localhost.man'}
-        },
         'storage.periodic_tasks': {
             'task': 'storage.tasks.periodic_tasks.garbage_collector',
             'schedule': timedelta(hours=1),
@@ -67,24 +54,6 @@ celery.conf.update(
             'schedule': timedelta(hours=24),
             'options': {'queue': 'localhost.man'}
         },
-        'monitor.measure_response_time': {
-            'task': 'monitor.tasks.local_periodic_tasks.'
-                    'measure_response_time',
-            'schedule': timedelta(seconds=30),
-            'options': {'queue': 'localhost.man'}
-        },
-        'monitor.check_celery_queues': {
-            'task': 'monitor.tasks.local_periodic_tasks.'
-                    'check_celery_queues',
-            'schedule': timedelta(seconds=60),
-            'options': {'queue': 'localhost.man'}
-        },
-        'monitor.instance_per_template': {
-            'task': 'monitor.tasks.local_periodic_tasks.'
-                    'instance_per_template',
-            'schedule': timedelta(seconds=30),
-            'options': {'queue': 'localhost.man'}
-        },
     }
 
 )
diff --git a/circle/manager/moncelery.py b/circle/manager/moncelery.py
new file mode 100755
index 0000000..9b1f1a0
--- /dev/null
+++ b/circle/manager/moncelery.py
@@ -0,0 +1,66 @@
+# Copyright 2014 Budapest University of Technology and Economics (BME IK)
+#
+# This file is part of CIRCLE Cloud.
+#
+# CIRCLE is free software: you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option)
+# any later version.
+#
+# CIRCLE is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along
+# with CIRCLE.  If not, see <http://www.gnu.org/licenses/>.
+
+from celery import Celery
+from datetime import timedelta
+from kombu import Queue, Exchange
+from os import getenv
+
+HOSTNAME = "localhost"
+CACHE_URI = getenv("CACHE_URI", "pylibmc://127.0.0.1:11211/")
+
+celery = Celery('monitor',
+                broker=getenv("AMQP_URI"),
+                include=['vm.tasks.local_periodic_tasks',
+                         'monitor.tasks.local_periodic_tasks',
+                         ])
+
+celery.conf.update(
+    CELERY_RESULT_BACKEND='cache',
+    CELERY_CACHE_BACKEND=CACHE_URI,
+    CELERY_TASK_RESULT_EXPIRES=300,
+    CELERY_QUEUES=(
+        Queue(HOSTNAME + '.monitor', Exchange('monitor', type='direct'),
+              routing_key="monitor"),
+    ),
+    CELERYBEAT_SCHEDULE={
+        'vm.update_domain_states': {
+            'task': 'vm.tasks.local_periodic_tasks.update_domain_states',
+            'schedule': timedelta(seconds=10),
+            'options': {'queue': 'localhost.monitor'}
+        },
+        'monitor.measure_response_time': {
+            'task': 'monitor.tasks.local_periodic_tasks.'
+                    'measure_response_time',
+            'schedule': timedelta(seconds=30),
+            'options': {'queue': 'localhost.monitor'}
+        },
+        'monitor.check_celery_queues': {
+            'task': 'monitor.tasks.local_periodic_tasks.'
+                    'check_celery_queues',
+            'schedule': timedelta(seconds=60),
+            'options': {'queue': 'localhost.monitor'}
+        },
+        'monitor.instance_per_template': {
+            'task': 'monitor.tasks.local_periodic_tasks.'
+                    'instance_per_template',
+            'schedule': timedelta(seconds=30),
+            'options': {'queue': 'localhost.monitor'}
+        },
+    }
+
+)
diff --git a/circle/manager/slowcelery.py b/circle/manager/slowcelery.py
new file mode 100755
index 0000000..ee8eba1
--- /dev/null
+++ b/circle/manager/slowcelery.py
@@ -0,0 +1,50 @@
+# Copyright 2014 Budapest University of Technology and Economics (BME IK)
+#
+# This file is part of CIRCLE Cloud.
+#
+# CIRCLE is free software: you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option)
+# any later version.
+#
+# CIRCLE is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along
+# with CIRCLE.  If not, see <http://www.gnu.org/licenses/>.
+
+from celery import Celery
+from datetime import timedelta
+from kombu import Queue, Exchange
+from os import getenv
+
+HOSTNAME = "localhost"
+CACHE_URI = getenv("CACHE_URI", "pylibmc://127.0.0.1:11211/")
+
+celery = Celery('manager.slow',
+                broker=getenv("AMQP_URI"),
+                include=['vm.tasks.local_tasks',
+                         'vm.tasks.local_periodic_tasks',
+                         'storage.tasks.local_tasks',
+                         'storage.tasks.periodic_tasks',
+                         ])
+
+celery.conf.update(
+    CELERY_RESULT_BACKEND='cache',
+    CELERY_CACHE_BACKEND=CACHE_URI,
+    CELERY_TASK_RESULT_EXPIRES=300,
+    CELERY_QUEUES=(
+        Queue(HOSTNAME + '.man.slow', Exchange('manager.slow', type='direct'),
+              routing_key="manager.slow"),
+    ),
+    CELERYBEAT_SCHEDULE={
+        'vm.garbage_collector': {
+            'task': 'vm.tasks.local_periodic_tasks.garbage_collector',
+            'schedule': timedelta(minutes=10),
+            'options': {'queue': 'localhost.man.slow'}
+        },
+    }
+
+)
diff --git a/circle/storage/models.py b/circle/storage/models.py
index 54a1eb8..f9df81c 100644
--- a/circle/storage/models.py
+++ b/circle/storage/models.py
@@ -278,7 +278,7 @@ class Disk(TimeStampedModel):
 
         return Disk.create(base=self, datastore=self.datastore,
                            name=self.name, size=self.size,
-                           type=new_type)
+                           type=new_type, dev_num=self.dev_num)
 
     def get_vmdisk_desc(self):
         """Serialize disk object to the vmdriver.
diff --git a/circle/vm/operations.py b/circle/vm/operations.py
index 8155707..b14895c 100644
--- a/circle/vm/operations.py
+++ b/circle/vm/operations.py
@@ -41,7 +41,7 @@ from .models import (
     Instance, InstanceActivity, InstanceTemplate, Interface, Node,
     NodeActivity, pwgen
 )
-from .tasks import agent_tasks
+from .tasks import agent_tasks, local_agent_tasks
 
 from dashboard.store_api import Store, NoStoreException
 
@@ -153,6 +153,7 @@ class AddInterfaceOperation(InstanceOperation):
                     self.rollback(net, activity)
                 raise
             net.deploy()
+            local_agent_tasks.send_networking_commands(self.instance, activity)
 
     def get_activity_name(self, kwargs):
         return create_readable(ugettext_noop("add %(vlan)s interface"),
@@ -218,6 +219,7 @@ class DownloadDiskOperation(InstanceOperation):
     has_percentage = True
     required_perms = ('storage.download_disk', )
     accept_states = ('STOPPED', 'PENDING', 'RUNNING')
+    async_queue = "localhost.man.slow"
 
     def _operation(self, user, url, task, activity, name=None):
         activity.result = url
@@ -368,6 +370,7 @@ class MigrateOperation(InstanceOperation):
     required_perms = ()
     superuser_required = True
     accept_states = ('RUNNING', )
+    async_queue = "localhost.man.slow"
 
     def rollback(self, activity):
         with activity.sub_activity(
@@ -512,6 +515,7 @@ class SaveAsTemplateOperation(InstanceOperation):
     abortable = True
     required_perms = ('vm.create_template', )
     accept_states = ('RUNNING', 'PENDING', 'STOPPED')
+    async_queue = "localhost.man.slow"
 
     def is_preferred(self):
         return (self.instance.is_base and
@@ -667,6 +671,7 @@ class SleepOperation(InstanceOperation):
     required_perms = ()
     accept_states = ('RUNNING', )
     resultant_state = 'SUSPENDED'
+    async_queue = "localhost.man.slow"
 
     def is_preferred(self):
         return (not self.instance.is_base and
@@ -839,6 +844,7 @@ class FlushOperation(NodeOperation):
     description = _("Disable node and move all instances to other ones.")
     required_perms = ()
     superuser_required = True
+    async_queue = "localhost.man.slow"
 
     def on_abort(self, activity, error):
         from manager.scheduler import TraitsUnsatisfiableException
@@ -998,12 +1004,12 @@ class MountStoreOperation(EnsureAgentMixin, InstanceOperation):
         except NoStoreException:
             raise PermissionDenied  # not show the button at all
 
-    def _operation(self):
+    def _operation(self, user):
         inst = self.instance
         queue = self.instance.get_remote_queue_name("agent")
         host = urlsplit(settings.STORE_URL).hostname
-        username = Store(inst.owner).username
-        password = inst.owner.profile.smb_password
+        username = Store(user).username
+        password = user.profile.smb_password
         agent_tasks.mount_store.apply_async(
             queue=queue, args=(inst.vm_name, host, username, password))
 
diff --git a/circle/vm/tasks/agent_tasks.py b/circle/vm/tasks/agent_tasks.py
index 13af817..5528735 100644
--- a/circle/vm/tasks/agent_tasks.py
+++ b/circle/vm/tasks/agent_tasks.py
@@ -76,3 +76,8 @@ def get_keys(vm):
 @celery.task(name='agent.send_expiration')
 def send_expiration(vm, url):
     pass
+
+
+@celery.task(name='agent.change_ip')
+def change_ip(vm, interfaces, dns):
+    pass
diff --git a/circle/vm/tasks/local_agent_tasks.py b/circle/vm/tasks/local_agent_tasks.py
index 27b471b..2e54510 100644
--- a/circle/vm/tasks/local_agent_tasks.py
+++ b/circle/vm/tasks/local_agent_tasks.py
@@ -19,7 +19,9 @@ from common.models import create_readable
 from manager.mancelery import celery
 from vm.tasks.agent_tasks import (restart_networking, change_password,
                                   set_time, set_hostname, start_access_server,
-                                  cleanup, update)
+                                  cleanup, update, change_ip)
+from firewall.models import Host
+
 import time
 from base64 import encodestring
 from StringIO import StringIO
@@ -31,13 +33,11 @@ from celery.result import TimeoutError
 from monitor.client import Client
 
 
-def send_init_commands(instance, act, vm):
+def send_init_commands(instance, act):
+    vm = instance.vm_name
     queue = instance.get_remote_queue_name("agent")
     with act.sub_activity('cleanup', readable_name=ugettext_noop('cleanup')):
         cleanup.apply_async(queue=queue, args=(vm, ))
-    with act.sub_activity('restart_networking',
-                          readable_name=ugettext_noop('restart networking')):
-        restart_networking.apply_async(queue=queue, args=(vm, ))
     with act.sub_activity('change_password',
                           readable_name=ugettext_noop('change password')):
         change_password.apply_async(queue=queue, args=(vm, instance.pw))
@@ -49,6 +49,17 @@ def send_init_commands(instance, act, vm):
             queue=queue, args=(vm, instance.primary_host.hostname))
 
 
+def send_networking_commands(instance, act):
+    queue = instance.get_remote_queue_name("agent")
+    with act.sub_activity('change_ip',
+                          readable_name=ugettext_noop('change ip')):
+        change_ip.apply_async(queue=queue, args=(
+            instance.vm_name, ) + get_network_configs(instance))
+    with act.sub_activity('restart_networking',
+                          readable_name=ugettext_noop('restart networking')):
+        restart_networking.apply_async(queue=queue, args=(instance.vm_name, ))
+
+
 def create_agent_tar():
     def exclude(tarinfo):
         if tarinfo.name.startswith('./.git'):
@@ -94,8 +105,9 @@ def agent_started(vm, version=None):
 
         if not initialized:
             measure_boot_time(instance)
-            send_init_commands(instance, act, vm)
+            send_init_commands(instance, act)
 
+        send_networking_commands(instance, act)
         with act.sub_activity(
             'start_access_server',
             readable_name=ugettext_noop('start access server')
@@ -134,6 +146,13 @@ def agent_stopped(vm):
         pass
 
 
+def get_network_configs(instance):
+    interfaces = {}
+    for host in Host.objects.filter(interface__instance=instance):
+        interfaces[str(host.mac)] = host.get_network_config()
+    return (interfaces, settings.FIREWALL_SETTINGS['rdns_ip'])
+
+
 def update_agent(instance, act=None):
     if act:
         act = act.sub_activity(
diff --git a/miscellaneous/manager.conf b/miscellaneous/manager.conf
new file mode 100644
index 0000000..291d323
--- /dev/null
+++ b/miscellaneous/manager.conf
@@ -0,0 +1,16 @@
+description     "CIRCLE manager"
+
+start on runlevel [2345]
+stop on runlevel [!2345]
+
+pre-start script
+    start moncelery
+    start mancelery
+    start slowcelery
+end script
+
+post-stop script
+    stop moncelery
+    stop mancelery
+    stop slowcelery
+end script
diff --git a/miscellaneous/mancelery.conf b/miscellaneous/mancelery.conf
index 6972593..a6f63c6 100644
--- a/miscellaneous/mancelery.conf
+++ b/miscellaneous/mancelery.conf
@@ -1,10 +1,8 @@
-description     "CIRCLE mancelery"
-
-start on runlevel [2345]
-stop on runlevel [!2345]
+description     "CIRCLE mancelery for common jobs"
 
 respawn
 respawn limit 30 30
+
 setgid cloud
 setuid cloud
 
@@ -12,6 +10,5 @@ script
     cd /home/cloud/circle/circle
     . /home/cloud/.virtualenvs/circle/bin/activate
     . /home/cloud/.virtualenvs/circle/bin/postactivate
-    exec ./manage.py celery --app=manager.mancelery worker --autoreload --loglevel=info --hostname=mancelery -B -c 1
+    exec ./manage.py celery --app=manager.mancelery worker --autoreload --loglevel=info --hostname=mancelery -B -c 10
 end script
-
diff --git a/miscellaneous/moncelery.conf b/miscellaneous/moncelery.conf
new file mode 100644
index 0000000..ca00325
--- /dev/null
+++ b/miscellaneous/moncelery.conf
@@ -0,0 +1,14 @@
+description     "CIRCLE moncelery for monitoring jobs"
+
+respawn
+respawn limit 30 30
+
+setgid cloud
+setuid cloud
+
+script
+    cd /home/cloud/circle/circle
+    . /home/cloud/.virtualenvs/circle/bin/activate
+    . /home/cloud/.virtualenvs/circle/bin/postactivate
+    exec ./manage.py celery --app=manager.moncelery worker --autoreload --loglevel=info --hostname=moncelery -B -c 3
+end script
diff --git a/miscellaneous/portal-uwsgi.conf b/miscellaneous/portal-uwsgi.conf
index bc2cbeb..3d0663b 100644
--- a/miscellaneous/portal-uwsgi.conf
+++ b/miscellaneous/portal-uwsgi.conf
@@ -12,4 +12,3 @@ script
     . /home/cloud/.virtualenvs/circle/bin/postactivate
     exec /home/cloud/.virtualenvs/circle/bin/uwsgi --chdir=/home/cloud/circle/circle -H /home/cloud/.virtualenvs/circle --socket /tmp/uwsgi.sock --wsgi-file circle/wsgi.py --chmod-socket=666
 end script
-
diff --git a/miscellaneous/portal.conf b/miscellaneous/portal.conf
index fcc2a0d..ce1d2c9 100644
--- a/miscellaneous/portal.conf
+++ b/miscellaneous/portal.conf
@@ -14,4 +14,3 @@ script
     . /home/cloud/.virtualenvs/circle/bin/postactivate
     exec ./manage.py runserver '[::]:8080'
 end script
-
diff --git a/miscellaneous/slowcelery.conf b/miscellaneous/slowcelery.conf
new file mode 100644
index 0000000..b4fdc75
--- /dev/null
+++ b/miscellaneous/slowcelery.conf
@@ -0,0 +1,14 @@
+description     "CIRCLE mancelery for slow jobs"
+
+respawn
+respawn limit 30 30
+
+setgid cloud
+setuid cloud
+
+script
+    cd /home/cloud/circle/circle
+    . /home/cloud/.virtualenvs/circle/bin/activate
+    . /home/cloud/.virtualenvs/circle/bin/postactivate
+    exec ./manage.py celery --app=manager.slowcelery worker --autoreload --loglevel=info --hostname=slowcelery -B -c 5
+end script