diff --git a/roles/apache2/tasks/apacheRedHat.yml b/roles/apache2/tasks/apacheRedHat.yml
index 584ed275655dbff3b919d20679e9c8ce3a56be03..71e520a982b4be7552aaeea70c55bb83b68c9b4c 100644
--- a/roles/apache2/tasks/apacheRedHat.yml
+++ b/roles/apache2/tasks/apacheRedHat.yml
@@ -3,7 +3,7 @@
 -
  name: "Installing Apache"
  sudo: true
- yum: name={{ item }} state=latest
+ yum: name={{ item }} state=present
  with_items:
   - mod_ssl
   - mod_wsgi 
diff --git a/roles/extra_rpms/tasks/main.yml b/roles/extra_rpms/tasks/main.yml
index 8dcf07de56a4a03f8cf52aaf3349a5a8193d224d..2a85fba6ddd111326b878ba24e599bc1dc12f5d2 100644
--- a/roles/extra_rpms/tasks/main.yml
+++ b/roles/extra_rpms/tasks/main.yml
@@ -1,6 +1,6 @@
 ---
 - name: "Install extra packages"
-  yum: "name={{ item }} state=latest"
+  yum: "name={{ item }} state=present"
   with_items:
     pkgs
   sudo: true
diff --git a/roles/fastest_mirror/tasks/main.yml b/roles/fastest_mirror/tasks/main.yml
index b5f720a809cca3eb72381fbaea754def989fafd3..7b18f9451a9a422eb2f25fbef9faa60cb608960a 100644
--- a/roles/fastest_mirror/tasks/main.yml
+++ b/roles/fastest_mirror/tasks/main.yml
@@ -11,3 +11,10 @@
   command: yum makecache
   sudo: true
   when: ansible_os_family == 'RedHat'
+
+# For some reason ed went missing from the NeCTAR official CentOS 7 image
+# This meant that fail2ban could ban you, but could never unban you
+- name: "make sure ed is installed"
+  yum: name=ed state=installed
+  sudo: true
+  when: ansible_os_family == 'RedHat'
diff --git a/roles/gluster_server/files/glusterfs-epel.repo b/roles/gluster_server/files/glusterfs-epel.repo
index 843b4baef3cf4d81aca369e49c44b92c1599c3cf..6cac832a40534526c9e689321cb8a8b1f271c5f7 100644
--- a/roles/gluster_server/files/glusterfs-epel.repo
+++ b/roles/gluster_server/files/glusterfs-epel.repo
@@ -2,21 +2,21 @@
 
 [glusterfs-epel]
 name=GlusterFS is a clustered file-system capable of scaling to several petabytes.
-baseurl=http://download.gluster.org/pub/gluster/glusterfs/3.6/LATEST/EPEL.repo/epel-$releasever/$basearch/
+baseurl=http://download.gluster.org/pub/gluster/glusterfs/3.7/LATEST/EPEL.repo/epel-$releasever/$basearch/
 enabled=1
 skip_if_unavailable=1
 gpgcheck=0
 
 [glusterfs-noarch-epel]
 name=GlusterFS is a clustered file-system capable of scaling to several petabytes.
-baseurl=http://download.gluster.org/pub/gluster/glusterfs/3.6/LATEST/EPEL.repo/epel-$releasever/noarch
+baseurl=http://download.gluster.org/pub/gluster/glusterfs/3.7/LATEST/EPEL.repo/epel-$releasever/noarch
 enabled=1
 skip_if_unavailable=1
 gpgcheck=0
 
 [glusterfs-source-epel]
 name=GlusterFS is a clustered file-system capable of scaling to several petabytes. - Source
-baseurl=http://download.gluster.org/pub/gluster/glusterfs/3.6/LATEST/EPEL.repo/epel-$releasever/SRPMS
+baseurl=http://download.gluster.org/pub/gluster/glusterfs/3.7/LATEST/EPEL.repo/epel-$releasever/SRPMS
 enabled=0
 skip_if_unavailable=1
 gpgcheck=0
diff --git a/roles/installPackage/tasks/main.yml b/roles/installPackage/tasks/main.yml
index d8605ffc42082e877b9714363c88ce3182b57166..a42426cb3e5fe964c18da7a8870c1729446ce213 100644
--- a/roles/installPackage/tasks/main.yml
+++ b/roles/installPackage/tasks/main.yml
@@ -14,7 +14,7 @@
   when: ansible_distribution == 'CentOS' and importRepo is defined
 
 - name: Install yum packages 
-  yum: name={{ item }} state=latest
+  yum: name={{ item }} state=present
   with_items: yumPackageList
   sudo: true
   when: ansible_distribution == 'CentOS' and yumPackageList is defined
diff --git a/roles/karaage2.7/tasks/main.yml b/roles/karaage2.7/tasks/main.yml
index 279b5d5250b99d667a2b51ec9b1e4f881760343a..4512a69b07c8243dc057b1034c90a821d42331ce 100644
--- a/roles/karaage2.7/tasks/main.yml
+++ b/roles/karaage2.7/tasks/main.yml
@@ -2,7 +2,7 @@
 - include_vars: "{{ ansible_distribution }}_{{ ansible_distribution_version }}_{{ ansible_architecture }}.yml"
 
 - name: install system packages apt
-  apt: name={{ item }} state=installed update_cache=true
+  apt: name={{ item }} state=installed
   sudo: true
   with_items: system_packages
   when: ansible_os_family == 'Debian'
diff --git a/roles/karaage3.1.17/tasks/karaage.yml b/roles/karaage3.1.17/tasks/karaage.yml
index 3ee091ecb4b0458a9fe070492c3c4343265edd8c..c93567691305ebdc4efcc535e2ecd478e0286546 100644
--- a/roles/karaage3.1.17/tasks/karaage.yml
+++ b/roles/karaage3.1.17/tasks/karaage.yml
@@ -26,7 +26,7 @@
 
 -
  name: "Installing prerequisites Redhat"
- yum: name={{ item }} state=latest
+ yum: name={{ item }} state=present
  sudo: true
  with_items:
   - libxml2-devel
diff --git a/roles/ldapclient/tasks/installOpenLdap.yml b/roles/ldapclient/tasks/installOpenLdap.yml
index 31a12286fd7b829b272cb6a68812f15478274b75..b11a480d754812d7c4f7139611502dcb1219fcf4 100644
--- a/roles/ldapclient/tasks/installOpenLdap.yml
+++ b/roles/ldapclient/tasks/installOpenLdap.yml
@@ -1,6 +1,6 @@
 ---
 - name: "Install open ldap package yum"
-  yum: name={{ item }} state=latest
+  yum: name={{ item }} state=present
   with_items:
     - openldap
     - openldap-clients
@@ -13,7 +13,7 @@
   when: ansible_os_family == 'RedHat'
 
 - name: "Install open ldap package apt"
-  action: apt pkg={{ item }} state=installed 
+  action: apt pkg={{ item }} state=present
   with_items:
     - ldap-utils
     - sssd 
diff --git a/roles/link_usr_local/tasks/main.yml b/roles/link_usr_local/tasks/main.yml
index 72847692aec9dcbd7d0a654449cfac308243c549..091d49c29e80bcb470bd909a41c1ff84f2ab3b75 100644
--- a/roles/link_usr_local/tasks/main.yml
+++ b/roles/link_usr_local/tasks/main.yml
@@ -3,6 +3,10 @@
   stat: path={{ dest }}
   register: stat_r
 
+
+- name: debug1
+  debug: var=stat_r
+
 - name: mv
   command: mv "{{ dest }}" "{{ dest }}_old"
   when: stat_r.stat.exists and stat_r.stat.isdir
@@ -12,6 +16,8 @@
   stat: path={{ dest }}
   register: stat_r
 
+- name: debug2
+  debug: var=stat_r
 
 - name: link
   file: src="{{ src }}" dest="{{ dest }}" state=link
diff --git a/roles/mellanox_drivers/tasks/main.yml b/roles/mellanox_drivers/tasks/main.yml
index a240e27b1918784dd6629e0baabca37e5cc5cb65..a662dc369342369848fe56b0d4a1bf1590463901 100644
--- a/roles/mellanox_drivers/tasks/main.yml
+++ b/roles/mellanox_drivers/tasks/main.yml
@@ -14,30 +14,32 @@
   register: drivers_installed
   ignore_errors: true
 
-- name: yum update to upgrade kernel
-  shell: "yum update -y"
-  sudo: true
-  ignore_errors: true
-  when: ansible_os_family == "RedHat" and  drivers_installed|failed
+
+# This is NASTY. Don't upgrade production systems without taking them out of the queue first.
+#- name: yum update to upgrade kernel
+#  shell: "yum update -y"
+#  sudo: true
+#  ignore_errors: true
+#  when: ansible_os_family == "RedHat" and  drivers_installed|failed
   
 #
 # A REBOOT IS NEEDED AFTER a KERNEL UPDATE
 #
-- name: restart machine
-  shell: sleep 5; sudo shutdown -r now "Ansible updates triggered"
-  async: 2
-  poll: 0
-  ignore_errors: true
-  sudo: true
-  when: ansible_os_family == "RedHat" and  drivers_installed|failed
-
-- name: waiting for server to come back
-  local_action: wait_for host={{ ansible_ssh_host }} state=started port=22 delay=10 search_regex=OpenSSH
-  sudo: false
-
-- name: waiting for server to come back number 2
-  local_action: wait_for host={{ ansible_ssh_host }} state=started port=22 delay=10 search_regex=OpenSSH
-  sudo: false
+#- name: restart machine
+#  shell: sleep 5; sudo shutdown -r now "Ansible updates triggered"
+#  async: 2
+#  poll: 0
+#  ignore_errors: true
+#  sudo: true
+#  when: ansible_os_family == "RedHat" and  drivers_installed|failed
+#
+#- name: waiting for server to come back
+#  local_action: wait_for host={{ ansible_ssh_host }} state=started port=22 delay=10 search_regex=OpenSSH
+#  sudo: false
+#
+#- name: waiting for server to come back number 2
+#  local_action: wait_for host={{ ansible_ssh_host }} state=started port=22 delay=10 search_regex=OpenSSH
+#  sudo: false
 
 
 - name: copy driver source
@@ -89,6 +91,7 @@
       insertafter: "auto {{ MELLANOX_DEVICE_NAME }}"
   sudo: true
   when: ansible_os_family=="Debian" and  drivers_installed|failed
+
 - name: Ubuntu network interfaces - line 3
   lineinfile:
   args: 
@@ -107,7 +110,7 @@
   poll: 0
   ignore_errors: true
   sudo: true
-  when: ansible_os_family=="Centos" and  drivers_installed|failed
+  when: ansible_os_family=="RedHat" and  drivers_installed|failed
 
 - name: restart machine for Ubuntu -cos it is 'special'
   shell: "sleep 5; sudo shutdown -r now"
@@ -115,19 +118,21 @@
   poll: 1
   ignore_errors: true
   sudo: true
-  when: ansible_os_family=="Debian"
+  when: ansible_os_family=="Debian" and  drivers_installed|failed
 
 - name: waiting for server to come back
   local_action: wait_for host={{ ansible_ssh_host }} state=started port=22 delay=10 search_regex=OpenSSH
   sudo: false
+  when: drivers_installed|failed
 
 - name: waiting for server to come back 2
   local_action: wait_for host={{ ansible_ssh_host }} state=started port=22 delay=10 search_regex=OpenSSH
+  when: drivers_installed|failed
 
 - name: bring up interface
   #variable=eth0 or ens6
   command: ifup {{ MELLANOX_DEVICE_NAME }} 
   sudo: true
-  when: ansible_distribution_major_version == "7"
+  when: ansible_os_family=="RedHat" and ansible_distribution_major_version == "7"
    
   
diff --git a/roles/move_homedir/tasks/main.yml b/roles/move_homedir/tasks/main.yml
index d81c8fe3bc0711b5d9fa3389577f60d11fbc37ae..9ed97c5d5d6dcd1098e8a734af3d8d926aa67260 100644
--- a/roles/move_homedir/tasks/main.yml
+++ b/roles/move_homedir/tasks/main.yml
@@ -13,43 +13,12 @@
   lineinfile:
   args:
     dest: /etc/passwd
-    regexp: "{{ ansible_ssh_user }}:x:1001:1001::/home/{{ ansible_ssh_user }}:.*"
-    line: "{{ ansible_ssh_user }}:x:1001:1001::/local_home/{{ ansible_ssh_user }}:/bin/bash"
+    regexp: '{{ ansible_ssh_user }}:x:(.*):(.*):(.*):/home/{{ ansible_ssh_user }}:(.*)'
+    line: '{{ ansible_ssh_user }}:x:\1:\2:\3:/local_home/{{ ansible_ssh_user }}:\4'
     backrefs: yes
   sudo: true
-  register: edit1
+  register: edit
 
 
-- name: edit passwd file
-  lineinfile:
-  args:
-    dest: /etc/passwd
-    regexp: "{{ ansible_ssh_user }}:x:500:500::/home/{{ ansible_ssh_user }}:.*"
-    line: "{{ ansible_ssh_user }}:x:500:500::/local_home/{{ ansible_ssh_user }}:/bin/bash"
-    backrefs: yes
-  sudo: true
-  register: edit2
-
-
-
-- name: edit passwd file
-  lineinfile:
-  args:
-    dest: /etc/passwd
-    regexp: "{{ ansible_ssh_user }}:x:1000:1000::/home/{{ ansible_ssh_user }}:.*"
-    line: "{{ ansible_ssh_user }}:x:1000:1000::/local_home/{{ ansible_ssh_user }}:/bin/bash"
-    backrefs: yes
-  sudo: true
-  register: edit3
 
-# ubuntu:x:1000:1000:Ubuntu:/home/ubuntu:/bin/bash
-- name: edit passwd file for ubuntu 14
-  lineinfile:
-  args:
-    dest: /etc/passwd
-    regexp: "{{ ansible_ssh_user }}:x:1000:1000:Ubuntu:/home/{{ ansible_ssh_user }}:.*"
-    line: "{{ ansible_ssh_user }}:x:1000:1000:Ubuntu:/local_home/{{ ansible_ssh_user }}:/bin/bash"
-    backrefs: yes
-  sudo: true
-  register: edit4
 
diff --git a/roles/mysql/tasks/mysql_client.yml b/roles/mysql/tasks/mysql_client.yml
index f8c23a1ce160d20be5df10b9f76da1e0f5ca3801..05a1022d073868f6f2cd19bc21ae905871a6e64e 100644
--- a/roles/mysql/tasks/mysql_client.yml
+++ b/roles/mysql/tasks/mysql_client.yml
@@ -6,7 +6,7 @@
   when: ansible_os_family == "Debian"
 
 - name: Installing MySQL RedHat
-  yum: name="{{ item }}" state=latest
+  yum: name="{{ item }}" state=present
   with_items: client_packages
   sudo: true
   when: ansible_os_family == "RedHat"
diff --git a/roles/nfs-common/tasks/aptPackages.yml b/roles/nfs-common/tasks/aptPackages.yml
index 364b2b73093be8d9ac7b80c63bd53025d3694713..3244c7d1890613902b95c7f572059d905619b79e 100644
--- a/roles/nfs-common/tasks/aptPackages.yml
+++ b/roles/nfs-common/tasks/aptPackages.yml
@@ -4,6 +4,6 @@
   with_items:
     - nfs-common
     - nfs-kernel-server
-  apt: "name={{ item }} state=latest"
+  apt: "name={{ item }} state=present"
   sudo: true
 
diff --git a/roles/nfs-common/tasks/yumPackages.yml b/roles/nfs-common/tasks/yumPackages.yml
index c6daa0dc26c42e352d8027edeb938503fc2f7cf4..36da380ff649f49f291e153a26e352651111b4c3 100644
--- a/roles/nfs-common/tasks/yumPackages.yml
+++ b/roles/nfs-common/tasks/yumPackages.yml
@@ -4,5 +4,5 @@
   with_items: 
     - bind-utils
     - nfs-utils
-  yum: "name={{ item }} state=latest"
+  yum: "name={{ item }} state=present"
   sudo: true
diff --git a/roles/nfs-server/tasks/main.yml b/roles/nfs-server/tasks/main.yml
index bde7943086ed49798b340a43dcbad5808836e1d9..c317d2ae0b5fe6668f288ec074ae9f8dc0eff25c 100644
--- a/roles/nfs-server/tasks/main.yml
+++ b/roles/nfs-server/tasks/main.yml
@@ -1,6 +1,6 @@
 ---
 - name: install nfs kernel server
-  apt: name=nfs-kernel-server state=latest
+  apt: name=nfs-kernel-server state=present
   sudo: true
   when: ansible_os_family == "Debian"
 
diff --git a/roles/package_update/tasks/main.yml b/roles/package_update/tasks/main.yml
deleted file mode 100644
index acbd63e0395b03dd4fe71fd80d203d1c1abc1405..0000000000000000000000000000000000000000
--- a/roles/package_update/tasks/main.yml
+++ /dev/null
@@ -1,13 +0,0 @@
----
-
-- name: "update cache centos"
-  shell: yum update -y
-  sudo: true
-  when: ansible_os_family == 'RedHat'
-
-- name: "update cache debian"
-  shell: apt-get update -y
-  sudo: true
-  when: ansible_os_family == 'Debian'
-
-
diff --git a/roles/provision_homedir/tasks/main.yml b/roles/provision_homedir/tasks/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..a057f44fc0932ef5f67a2f2a5de9e1531a1120b5
--- /dev/null
+++ b/roles/provision_homedir/tasks/main.yml
@@ -0,0 +1,25 @@
+---
+- name: make  dir
+  file: path="{{ provision_homedir | dirname }}" state=directory mode=755 owner=root
+  sudo: true
+  run_once: true
+
+- name: install python packages
+  yum: name=python-ldap state=installed
+  sudo: true
+  when: ansible_os_family == 'RedHat'
+
+- name: install python packages
+  apt: name=python-ldap state=installed
+  sudo: true
+  when: ansible_os_family == 'Debian'
+
+- name: copy provision_homedir template 
+  template: src=provision_homedir.py.j2 dest={{ provision_homedir }} mode=700 owner=root
+  sudo: true
+  run_once: true
+
+# the lockfile for makeing home directories should be located on the shared directory where the home directories will be created. Otherwise it will be racey
+- name: provision_homedir cron job 
+  cron: name=provision_homedir job="/usr/bin/flock -x -n /home/provision.lck -c {{ provision_homedir }}" user=root minute=*/30 state=present
+  sudo: true
diff --git a/roles/provision_homedir/templates/provision_homedir.py.j2 b/roles/provision_homedir/templates/provision_homedir.py.j2
new file mode 100644
index 0000000000000000000000000000000000000000..b601f099540b6c3126bcc4137001d6579fe69278
--- /dev/null
+++ b/roles/provision_homedir/templates/provision_homedir.py.j2
@@ -0,0 +1,73 @@
+#!/usr/bin/python
+import ldap
+import traceback
+import os
+import stat
+
+class ldapSearchConfig:
+    def __init__(self):
+        self.ldapserver=""
+        self.binddn=""
+        self.bindpw=""
+        self.baseDN=""
+        self.searchFilter=""
+        self.cacertfile=''
+
+class genericUser:
+    def __init__(self):
+        self.dn=""
+        self.cn=""
+        self.entry=""
+	self.uid=""
+
+
+def get_users(server):
+#    ldap.set_option(ldap.OPT_X_TLS_CACERTFILE,server.cacertfile)
+    ldap.set_option( ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER )
+    l=ldap.initialize(server.ldapserver)
+    l.simple_bind_s(server.binddn,server.bindpw)
+    retrieveAttributes = ["*"]
+    searchScope=ldap.SCOPE_SUBTREE
+    try:
+        ldap_result_id = l.search(server.baseDN,searchScope,server.searchFilter,retrieveAttributes)
+    except ldap.LDAPError, e:
+        pass
+    rtype,rdata = l.result(ldap_result_id,1)
+    allusers={}
+    for user in rdata:
+        dn=user[0]
+        attrs=user[1]
+        allusers[dn]=genericUser()
+        allusers[dn].dn=dn
+        allusers[dn].entry=attrs
+    return allusers
+
+
+def mk_homedir(path,uidNumber,gidNumber):
+	try:
+		statinfo = os.stat(path)
+	except OSError as e:
+		if 'No such file or directory' in e:
+			os.mkdir(path,0700)
+	statinfo = os.stat(path)
+	if stat.S_ISDIR(statinfo.st_mode):
+		if statinfo.st_gid != gidNumber or statinfo.st_uid!=uidNumber:
+			os.chown(path,uidNumber,gidNumber)
+	else:
+		raise Exception("users homedirectory is not a directory %s"%path)
+
+s=ldapSearchConfig()
+s.ldapserver="{{ ldapURI }}"
+s.binddn="{{ ldapBindDN }}"
+s.bindpw="{{ ldapBindDNPassword }}"
+s.baseDN="{{ ldapBase }}"
+s.searchFilter = "{{ search_filter }}"
+homeDirEntry= "{{ homeDirEntry }}"
+
+users=get_users(s)
+for user in users:
+	try:
+		mk_homedir(users[user].entry[homeDirEntry][0],int(users[user].entry['uidNumber'][0]),int(users[user].entry['gidNumber'][0]))
+	except:
+		print traceback.format_exc()
+		pass
diff --git a/roles/provision_homedir/vars/main.yml b/roles/provision_homedir/vars/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..f1b8ef6cdfbc9d1d7a245a3e607b5ec31dae9151
--- /dev/null
+++ b/roles/provision_homedir/vars/main.yml
@@ -0,0 +1,5 @@
+---
+use_active_directory: False
+provision_homedir: /usr/local/sbin/provision_homedir.py
+homeDirEntry: "{% if use_active_directory %}unixHomeDirectory{% else %}homeDirectory {% endif %}"
+search_filter: "{% if use_active_directory %}(unixHomeDirectory=*){% else %} (objectClass=posixAccount) {% endif %}"
diff --git a/roles/provision_slurm/tasks/main.yml b/roles/provision_slurm/tasks/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..6d4e6aa9ec44e1659825b4dce3ecfbb821550180
--- /dev/null
+++ b/roles/provision_slurm/tasks/main.yml
@@ -0,0 +1,25 @@
+---
+- name: make  dir
+  file: path="{{ provision_slurm | dirname }}" state=directory mode=755 owner=root
+  sudo: true
+  run_once: true
+
+- name: install python packages
+  yum: name=python-ldap state=installed
+  sudo: true
+  when: ansible_os_family == 'RedHat'
+
+- name: install python packages
+  apt: name=python-ldap state=installed
+  sudo: true
+  when: ansible_os_family == 'Debian'
+
+- name: copy provision_slurm template 
+  template: src=provision_slurm.py.j2 dest={{ provision_slurm }} mode=700 owner=root
+  sudo: true
+  run_once: true
+
+# the lockfile for makeing home directories should be located on the shared directory where the home directories will be created. Otherwise it will be racey
+- name: provision_slurm cron job 
+  cron: name=provision_slurm job="/usr/bin/flock -x -n /home/provision.lck -c {{ provision_slurm }}" user=root minute=*/30 state=present
+  sudo: true
diff --git a/roles/provision_slurm/templates/provision_slurm.py.j2 b/roles/provision_slurm/templates/provision_slurm.py.j2
new file mode 100644
index 0000000000000000000000000000000000000000..a8a6bca3cb4b0cb180364e13755b57595735410d
--- /dev/null
+++ b/roles/provision_slurm/templates/provision_slurm.py.j2
@@ -0,0 +1,76 @@
+#!/usr/bin/python
+import ldap
+import traceback
+import os
+import stat
+import subprocess
+
+class ldapSearchConfig:
+    def __init__(self):
+        self.ldapserver=""
+        self.binddn=""
+        self.bindpw=""
+        self.baseDN=""
+        self.searchFilter=""
+        self.cacertfile=''
+
+class genericUser:
+    def __init__(self):
+        self.dn=""
+        self.cn=""
+        self.entry=""
+	self.uid=""
+
+
+def get_users(server):
+#    ldap.set_option(ldap.OPT_X_TLS_CACERTFILE,server.cacertfile)
+    ldap.set_option( ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER )
+    l=ldap.initialize(server.ldapserver)
+    l.simple_bind_s(server.binddn,server.bindpw)
+    retrieveAttributes = ["*"]
+    searchScope=ldap.SCOPE_SUBTREE
+    try:
+        ldap_result_id = l.search(server.baseDN,searchScope,server.searchFilter,retrieveAttributes)
+    except ldap.LDAPError, e:
+        pass
+    rtype,rdata = l.result(ldap_result_id,1)
+    allusers={}
+    for user in rdata:
+        dn=user[0]
+        attrs=user[1]
+        allusers[dn]=genericUser()
+        allusers[dn].dn=dn
+        allusers[dn].entry=attrs
+    return allusers
+
+
+def mk_slurmaccount(acct):
+    output=subprocess.check_output(["{{ slurm_dir }}/bin/sacctmgr","--noheader","list","account",acct])
+    if acct in output:
+        return
+    else:
+        subprocess.call(["{{ slurm_dir }}/bin/sacctmgr","-i","create","account",acct])
+
+def mk_slurmuser(user,acct):
+    output=subprocess.check_output(["{{ slurm_dir }}/bin/sacctmgr","--noheader","list","Association","user=%s"%user,"format=account"])
+    if acct in output.splitlines():
+        return
+    else:
+        subprocess.call(["{{ slurm_dir }}/bin/sacctmgr","-i","create","user",user,"account=%s"%acct,"DefaultAccount=%s"%acct])
+
+
+s=ldapSearchConfig()
+s.ldapserver="{{ ldapURI }}"
+s.binddn="{{ ldapBindDN }}"
+s.bindpw="{{ ldapBindDNPassword }}"
+s.baseDN="{{ ldapBase }}"
+s.searchFilter = "{{ search_filter }}"
+
+users=get_users(s)
+mk_slurmaccount("default")
+for user in users:
+	try:
+                mk_slurmuser(users[user].entry['uid'][0],"default")
+	except:
+		print traceback.format_exc()
+		pass
diff --git a/roles/provision_slurm/vars/main.yml b/roles/provision_slurm/vars/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..2254544f25b1faea9c11c8b6ec3cf8e6e4e4d794
--- /dev/null
+++ b/roles/provision_slurm/vars/main.yml
@@ -0,0 +1,4 @@
+---
+use_active_directory: False
+provision_slurm: /usr/local/sbin/provision_slurm.py
+search_filter: "{% if use_active_directory %}(unixHomeDirectory=*){% else %} (objectClass=posixAccount) {% endif %}"
diff --git a/roles/slurm-build-rpms/tasks/main.yml b/roles/slurm-build-rpms/tasks/main.yml
deleted file mode 100644
index cbb3dca56d066b803ed0024782c2703e146e1c5e..0000000000000000000000000000000000000000
--- a/roles/slurm-build-rpms/tasks/main.yml
+++ /dev/null
@@ -1,95 +0,0 @@
----
-- name: install deps
-  yum: name={{ item }} state=installed
-  sudo: true
-  with_items:
-    - gcc
-    - rpm-build
-    - wget
-    - openssl-devel
-    - readline-devel
-    - pam-devel
-    - perl-ExtUtils-MakeMaker
-    - bzip2-devel
-    - mysql
-    - mysql-devel
-  when: ansible_os_family == "RedHat"
-
-- name: install deps
-  apt: name={{ item }} state=installed update_cache=yes
-  sudo: true
-  with_items:
-    - gcc
-    - wget
-    - libssl-dev
-    - libpam0g-dev
-    - libbz2-dev
-  when: ansible_os_family == "Debian"
-
-- name: get munge
-  shell: wget https://munge.googlecode.com/files/munge-{{ munge_version }}.tar.bz2
-  args:
-    chdir: /tmp
-    creates: /tmp/munge-{{ munge_version }}.tar.bz2
-
-- name: make munge rpms
-  shell: rpmbuild -ta --clean munge-{{ munge_version }}.tar.bz2
-  sudo: true
-  args:
-    chdir: /tmp
-    creates: /root/rpmbuild/RPMS/x86_64/munge-{{ munge_version }}-1.el6.x86_64.rpm
-  when: ansible_os_family == "RedHat"
-
-- name: untar munge
-  shell: tar jxf /tmp/munge-{{ munge_version }}.tar.bz2
-  sudo: true
-  args:
-    chdir: /tmp
-    creates: /tmp/munge-{{ munge_version }}
-  when: ansible_os_family == "Debian"
-
-- name: build munge
-  shell: configure && make && make install
-  sudo: true
-  args:
-    chdir: /tmp/munge-{{ munge_version }}
-  when: ansible_os_family == "Debian"
-
-- name: get slurm
-  shell: wget http://www.schedmd.com/download/latest/slurm-{{ slurm_version }}.tar.bz2
-  args:
-    chdir: /tmp
-    creates: /tmp/slurm-{{ slurm_version }}.tar.bz2
-
-- name: check munge installation
-  shell: rpm -qa munge
-  register: munge_installed
-  when: ansible_os_family == "RedHat"
-
-- name: install munge deps
-  shell: rpm -i /root/rpmbuild/RPMS/x86_64/munge-libs-{{ munge_version }}-1.el6.x86_64.rpm /root/rpmbuild/RPMS/x86_64/munge-{{ munge_version }}-1.el6.x86_64.rpm /root/rpmbuild/RPMS/x86_64/munge-devel-{{ munge_version }}-1.el6.x86_64.rpm
-  sudo: true
-  when: munge_installed.stdout.find("munge") == -1 
-
-- name: make slurm rpms
-  shell: rpmbuild -ta --clean slurm-{{ slurm_version }}.tar.bz2
-  sudo: true
-  args:
-    chdir: /tmp
-    creates: /root/rpmbuild/RPMS/x86_64/slurm-{{ slurm_version }}-1.el6.x86_64.rpm
-
-- name: copy rpms
-  shell: cp -r /root/rpmbuild /tmp
-  sudo: true
-  args:
-    creates: /tmp/rpmbuild/RPMS/x86_64/slurm-{{ slurm_version }}-1.el6.x86_64.rpm
-
-- name: retrieve rpms 1
-  shell: scp -o StrictHostKeyChecking=no -r {{ hostvars[ansible_hostname]['ansible_user_id'] }}@{{ ansible_ssh_host }}:/tmp/rpmbuild/ /tmp
-  delegate_to: 127.0.0.1
-  when: ansible_ssh_host is defined
-
-- name: retrieve rpms 2
-  shell: scp -r {{ hostvars[ansible_hostname]['ansible_user_id'] }}@{{ ansible_hostname }}:/tmp/rpmbuild/ /tmp
-  delegate_to: 127.0.0.1
-  when: ansible_ssh_host is not defined
diff --git a/roles/slurm-common/tasks/installMungeFromSource.yml b/roles/slurm-common/tasks/installMungeFromSource.yml
index aec3033b3534d3a3ddc43648a946df134b309ea8..06c72f5197dd8352b6c32d7d6838147b132b0b51 100644
--- a/roles/slurm-common/tasks/installMungeFromSource.yml
+++ b/roles/slurm-common/tasks/installMungeFromSource.yml
@@ -23,18 +23,22 @@
     chdir: /tmp/munge-{{ munge_version }}
     creates: "{{ munge_dir }}/bin/munge"
 
+- name: set use_systemd
+  set_fact: 
+    use_systemd: True
+  when: (ansible_distribution == "CentOS" or ansible_distribution == "RedHat") and ( ansible_distribution_major_version == "7") 
+
 - name: copy init script
   template: dest=/etc/init.d/munge src=munge.initd.j2 mode=755
   sudo: true
+  when: use_systemd is not defined
 
 - name:  copy slurm init script if OS contains systemd
   template: dest=/etc/systemd/system/munge.service src=munge.service.j2 mode=755
   sudo: true
-  when: (ansible_distribution == "CentOS" or ansible_distribution == "RedHat") and
-          ( ansible_distribution_major_version == "7")
+  when: use_systemd is defined
 
 - name: reload systemd
   shell: systemctl daemon-reload
   sudo: true
-  when: (ansible_distribution == "CentOS" or ansible_distribution == "RedHat") and
-          ( ansible_distribution_major_version == "7")
+  when: use_systemd is defined
diff --git a/roles/slurm-common/tasks/installSlurmFromSource.yml b/roles/slurm-common/tasks/installSlurmFromSource.yml
index ec9fbe5881b3188383da27589821cde48da977fa..c551d2392bb987b0990d48b34cee694ff275c425 100644
--- a/roles/slurm-common/tasks/installSlurmFromSource.yml
+++ b/roles/slurm-common/tasks/installSlurmFromSource.yml
@@ -19,6 +19,7 @@
   shell: tar jxf /tmp/slurm-{{ slurm_version }}.tar.bz2
   args:
     chdir: /tmp
+    creates: /tmp/slumr-{{ slurm_version }}
 
 - name: build slurm
   shell: ./configure --prefix={{ slurm_dir }} --with-munge={{ munge_dir }} && make
diff --git a/roles/slurm-common/tasks/main.yml b/roles/slurm-common/tasks/main.yml
index 31120c9385a9c1137fa6cf225b4cbbfa30de8379..a4f0080c14acbc49264c466e54565da733550424 100644
--- a/roles/slurm-common/tasks/main.yml
+++ b/roles/slurm-common/tasks/main.yml
@@ -27,17 +27,32 @@
   file: path={{ slurmdatadir }} state=directory owner=slurm group=slurm mode=755
   sudo: true
   when: slurmdatadir is defined 
+      
+- name: stat run directory
+  stat: path={{ slurmpiddir }} 
+  register: runstat
+  when: slurmpiddir is defined
 
 - name: create run directory
   file: path={{ slurmpiddir }} state=directory owner=root group=root mode=750
   sudo: true
-  when: slurmpiddir is defined 
+  when: slurmpiddir is defined and not runstat.stat.exists
+
+- name: create shared state directory
+  file: path={{slurmsharedstatedir }} state=directory owner=slurm group=slurm mode=750
+  sudo: true
+  run_once: true
+  when: usesharedstatedir
+
+- name: symlink shared state dir
+  file: path={{ slurmstatedir }} src={{ slurmsharedstatedir }} state=link
+  sudo: true
+  when: usesharedstatedir
 
 - name: create state directory
   file: path={{ slurmstatedir }} state=directory owner=slurm group=slurm mode=750
-
   sudo: true
-  when: slurmstatedir is defined 
+  when: slurmstatedir is defined  and not usesharedstatedir
 
 - name: create log directory
   file: path={{ slurmlogdir }} state=directory owner=slurm group=slurm mode=750
@@ -49,7 +64,7 @@
   sudo: true
 
 - name: install deps
-  yum: name={{ item }} state=latest
+  yum: name={{ item }} state=present
   with_items:
     - perl
     - perl-DBI
@@ -124,11 +139,11 @@
   when: slurm_gres_list is defined
 
 - name: install slurm prolog
-  template: src=slurm.prolog.j2 dest={{ slurm_dir }}/bin/slurm.prolog
+  template: src=slurm.prolog.j2 dest={{ slurm_dir }}/bin/slurm.prolog mode=755
   sudo: true
 
 - name: install slurm epilog
-  template: src=slurm.epilog.j2 dest={{ slurm_dir }}/bin/slurm.epilog
+  template: src=slurm.epilog.j2 dest={{ slurm_dir }}/bin/slurm.epilog mode=755
   sudo: true
 
 - name: install slurm.conf
diff --git a/roles/strudel_build/tasks/main.yml b/roles/strudel_build/tasks/main.yml
index c7e31d4477d37bb09f450f21137f342b37bcc658..21c8b806d06ffc8492b32d6e814aa2f72edef6ab 100644
--- a/roles/strudel_build/tasks/main.yml
+++ b/roles/strudel_build/tasks/main.yml
@@ -9,13 +9,6 @@
   when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "7"
   ignore_errors: true
 
-- name: add epel on CentOS 7
-  shell: yum -y update
-  sudo: true
-  when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "7"
-
-
-
 
 - name: install system packages apt
   apt: name={{ item }} state=installed update_cache=true
diff --git a/roles/strudel_config/templates/generic_slurm_config.json.j2 b/roles/strudel_config/templates/generic_slurm_config.json.j2
index 17ba6262ca1f5455c95b38aa6e174afcd627ffad..976557af150bb75b6fbc75891a895099d1a6ce66 100644
--- a/roles/strudel_config/templates/generic_slurm_config.json.j2
+++ b/roles/strudel_config/templates/generic_slurm_config.json.j2
@@ -1,9 +1,12 @@
 [
     [
-        "GenericDesktops"
+{% for partition in slurmqueues %}
+        "{{ partition.name }}"{% if not loop.last %},{% endif %}
+{% endfor %}
     ],
     {
-        "GenericDesktops": {
+{% for partition in slurmqueues %}
+        "{{ partition.name }}": {
             "__class__": "siteConfig",
             "__module__": "siteConfig",
             "agent": {
@@ -268,7 +271,7 @@
                 "__class__": "cmdRegEx",
                 "__module__": "siteConfig",
                 "async": false,
-                "cmd": "\"mkdir ~/.vnc ; rm -f ~/.vnc/clearpass ; touch ~/.vnc/clearpass ; chmod 600 ~/.vnc/clearpass ; passwd=\"'$'\"( dd if=/dev/urandom bs=1 count=8 2>/dev/null | md5sum | cut -b 1-8 ) ; echo \"'$'\"passwd > ~/.vnc/clearpass ; cat ~/.vnc/clearpass | vncpasswd -f > ~/.vnc/passwd ; chmod 600 ~/.vnc/passwd ; echo -e '#!/bin/bash\\nvncserver ; sleep 36000000 ' |  {{slurm_dir}}/bin/sbatch -p batch -N {nodes} -n {ppn} --time={hours}:00:00 -J desktop_{username} -o .vnc/slurm-%j.out \"",
+                "cmd": "\"mkdir ~/.vnc ; rm -f ~/.vnc/clearpass ; touch ~/.vnc/clearpass ; chmod 600 ~/.vnc/clearpass ; passwd=\"'$'\"( dd if=/dev/urandom bs=1 count=8 2>/dev/null | md5sum | cut -b 1-8 ) ; echo \"'$'\"passwd > ~/.vnc/clearpass ; cat ~/.vnc/clearpass | vncpasswd -f > ~/.vnc/passwd ; chmod 600 ~/.vnc/passwd ; echo -e '#!/bin/bash\\nexport PATH=\"'$'\"PATH:/bin ; vncserver ; sleep 36000000 ' |  {{slurm_dir}}/bin/sbatch -p {{ partition.name }} -N {nodes} -n {ppn} --time={hours}:00:00 -J desktop_{username} -o .vnc/slurm-%j.out \"",
                 "failFatal": true,
                 "formatFatal": false,
                 "host": "login",
@@ -345,7 +348,7 @@
                 "host": "exec",
                 "loop": false,
                 "regex": [
-                    "^.*?New 'X' desktop is \\S+(?P<vncDisplay>:[0-9]+)\\s*$"
+                    "^.*?New .* desktop is \\S+(?P<vncDisplay>:[0-9]+)\\s*$"
                 ],
                 "requireMatch": true
             },
@@ -447,6 +450,7 @@
                 ],
                 "requireMatch": true
             }
-        }
+        }{% if not loop.last %},{% endif %}
+{% endfor %}
     }
 ]
diff --git a/roles/vncserver/tasks/main.yml b/roles/vncserver/tasks/main.yml
index 59b754ea4eefd5f8af93eb3637413e65502d7d32..13c13dc639c66a9c031ecdfce3b5d84482de367e 100644
--- a/roles/vncserver/tasks/main.yml
+++ b/roles/vncserver/tasks/main.yml
@@ -23,20 +23,30 @@
   when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "7"
   ignore_errors: true
 
-- name: add epel on CentOS 7
-  shell: yum -y update
-  sudo: true
-  when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "7"
-
-
 - name: install system packages apt
-  apt: name={{ item }} state=installed update_cache=true  force=yes
+  apt: name={{ item }} state=present update_cache=true  force=yes
   sudo: true
   with_items: system_packages
   when: ansible_os_family == 'Debian'
 
+- name: yum group installs
+  shell: yum -y group install {{ item }}
+  sudo: true
+  with_items: system_group_packages
+  when: system_group_packages is defined
+
 - name: install system packages yum
-  yum: name={{ item }} state=installed update_cache=yes
+  yum: name={{ item }} state=present update_cache=yes
   sudo: true
   with_items: system_packages
   when: ansible_os_family == 'RedHat'
+
+- name: force the use of mate desktop
+  template: src=vncserver.centos dest=/bin/vncserver
+  sudo: true
+  when: ansible_os_family == 'RedHat'
+
+- name: force the use of mate desktop
+  template: src=vncserver.ubuntu dest=/usr/bin/vncserver
+  sudo: true
+  when: ansible_os_family == 'Debian'
diff --git a/roles/vncserver/templates/vncserver.centos b/roles/vncserver/templates/vncserver.centos
new file mode 100755
index 0000000000000000000000000000000000000000..e8d71f85521a9931e11c6d72c364cc5349c3d67b
--- /dev/null
+++ b/roles/vncserver/templates/vncserver.centos
@@ -0,0 +1,772 @@
+#!/usr/bin/perl
+#
+#  Copyright (C) 2009-2010 D. R. Commander.  All Rights Reserved.
+#  Copyright (C) 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
+#  Copyright (C) 2002-2003 Constantin Kaplinsky.  All Rights Reserved.
+#  Copyright (C) 2002-2005 RealVNC Ltd.
+#  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
+#
+#  This 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 2 of the License, or
+#  (at your option) any later version.
+#
+#  This software 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 this software; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
+#  USA.
+#
+
+#
+# vncserver - wrapper script to start an X VNC server.
+#
+
+#
+# First make sure we're operating in a sane environment.
+#
+
+$exedir = "";
+$slashndx = rindex($0, "/");
+if($slashndx>=0) {
+    $exedir = substr($0, 0, $slashndx+1);
+}
+
+$vncClasses = "";
+
+$xauth = "xauth";
+
+&SanityCheck();
+
+#
+# Global variables.  You may want to configure some of these for your site.
+#
+
+$geometry = "1024x768";
+#$depth = 16;
+$vncJavaFiles = (((-d "$vncClasses") && "$vncClasses") ||
+                 ((-d "/usr/share/vnc/classes") && "/usr/share/vnc/classes") ||
+                 ((-d "/usr/local/vnc/classes") && "/usr/local/vnc/classes"));
+                 
+$vncUserDir = "$ENV{HOME}/.vnc";
+$xauthorityFile = "$ENV{XAUTHORITY}" || "$ENV{HOME}/.Xauthority";
+
+$defaultXStartup
+    = ("#!/bin/sh\n\n".
+       "unset SESSION_MANAGER\n".
+       "unset DBUS_SESSION_BUS_ADDRESS\n".
+       "exec mate-session\n");
+
+chop($host = `uname -n`);
+
+if (-d "/etc/X11/fontpath.d") {
+    $fontPath = "catalogue:/etc/X11/fontpath.d";
+}
+
+@fontpaths = ('/usr/share/X11/fonts', '/usr/share/fonts', '/usr/share/fonts/X11/');
+if (! -l "/usr/lib/X11") {push(@fontpaths, '/usr/lib/X11/fonts');}
+if (! -l "/usr/X11") {push(@fontpaths, '/usr/X11/lib/X11/fonts');}
+if (! -l "/usr/X11R6") {push(@fontpaths, '/usr/X11R6/lib/X11/fonts');}
+push(@fontpaths, '/usr/share/fonts/default');
+
+@fonttypes = ('misc',
+             '75dpi',
+             '100dpi',
+             'Speedo',
+             'Type1');
+
+foreach $_fpath (@fontpaths) {
+    foreach $_ftype (@fonttypes) {
+        if (-f "$_fpath/$_ftype/fonts.dir") {
+            if (! -l "$_fpath/$_ftype") {
+                $defFontPath .= "$_fpath/$_ftype,";
+            }
+        }
+    }
+}
+
+if ($defFontPath) {
+    if (substr($defFontPath, -1, 1) == ',') {
+        chop $defFontPath;
+    }
+}
+
+if ($fontPath eq "") {
+    $fontPath = $defFontPath;
+}
+
+# Check command line options
+
+&ParseOptions("-geometry",1,"-depth",1,"-pixelformat",1,"-name",1,"-kill",1,
+	      "-help",0,"-h",0,"--help",0,"-fp",1,"-list",0,"-fg",0,"-autokill",0);
+
+&Usage() if ($opt{'-help'} || $opt{'-h'} || $opt{'--help'});
+
+&Kill() if ($opt{'-kill'});
+
+&List() if ($opt{'-list'});
+
+# Uncomment this line if you want default geometry, depth and pixelformat
+# to match the current X display:
+# &GetXDisplayDefaults();
+
+if ($opt{'-geometry'}) {
+    $geometry = $opt{'-geometry'};
+}
+if ($opt{'-depth'}) {
+    $depth = $opt{'-depth'};
+    $pixelformat = "";
+}
+if ($opt{'-pixelformat'}) {
+    $pixelformat = $opt{'-pixelformat'};
+}
+if ($opt{'-fp'}) {
+    $fontPath = $opt{'-fp'};
+    $fpArgSpecified = 1;
+}
+
+&CheckGeometryAndDepth();
+
+
+# Create the user's vnc directory if necessary.
+
+if (!(-e $vncUserDir)) {
+    if (!mkdir($vncUserDir,0755)) {
+	die "$prog: Could not create $vncUserDir.\n";
+    }
+}
+    
+# Check whether VNC authentication is enabled, and if so, prompt the user to
+# create a VNC password if they don't already have one.
+
+$securityTypeArgSpecified = 0;
+$vncAuthEnabled = 0;
+$passwordArgSpecified = 0;
+
+for ($i = 0; $i < @ARGV; ++$i) {
+    # -SecurityTypes can be followed by a space or "="
+    my @splitargs = split('=', $ARGV[$i]);
+    if (@splitargs <= 1 && $i < @ARGV - 1) {
+        push(@splitargs, $ARGV[$i + 1]);
+    }
+    if (lc(@splitargs[0]) eq "-securitytypes") {
+        if (@splitargs > 1) {
+            $securityTypeArgSpecified = 1;
+        }
+        foreach $arg2 (split(',', @splitargs[1])) {
+            if (lc($arg2) eq "vncauth" || lc($arg2) eq "tlsvnc"
+             || lc($arg2) eq "x509vnc") {
+                $vncAuthEnabled = 1;
+            }
+        }
+    }
+    if ((lc(@splitargs[0]) eq "-password")
+     || (lc(@splitargs[0]) eq "-passwordfile"
+     || (lc(@splitargs[0]) eq "-rfbauth"))) {
+        $passwordArgSpecified = 1;
+    }
+}
+
+if ((!$securityTypeArgSpecified || $vncAuthEnabled) && !$passwordArgSpecified) {
+    ($z,$z,$mode) = stat("$vncUserDir/passwd");
+    if (!(-e "$vncUserDir/passwd") || ($mode & 077)) {
+        warn "\nYou will require a password to access your desktops.\n\n";
+        system($exedir."vncpasswd -q $vncUserDir/passwd");
+        if (($? >> 8) != 0) {
+            exit 1;
+        }
+    }
+}
+ 
+# Find display number.
+
+if ((@ARGV > 0) && ($ARGV[0] =~ /^:(\d+)$/)) {
+    $displayNumber = $1;
+    shift(@ARGV);
+    if (!&CheckDisplayNumber($displayNumber)) {
+	die "A VNC server is already running as :$displayNumber\n";
+    }
+} elsif ((@ARGV > 0) && ($ARGV[0] !~ /^-/) && ($ARGV[0] !~ /^\+/)) {
+    &Usage();
+} else {
+    $displayNumber = &GetDisplayNumber();
+}
+
+$vncPort = 5900 + $displayNumber;
+
+$desktopLog = "$vncUserDir/$host:$displayNumber.log";
+unlink($desktopLog);
+
+# Make an X server cookie - use mcookie
+$cookie = `/usr/bin/mcookie`;
+open (XAUTH, "|xauth -f $xauthorityFile source -");
+print XAUTH "add $host:$displayNumber . $cookie\n";
+print XAUTH "add $host/unix:$displayNumber . $cookie\n";
+close XAUTH;
+
+if ($opt{'-name'}) {
+    $desktopName = $opt{'-name'};
+} else {
+    $desktopName = "$host:$displayNumber ($ENV{USER})";
+}
+
+# Now start the X VNC Server
+
+$cmd = $exedir."Xvnc :$displayNumber";
+$cmd .= " -desktop " . &quotedString($desktopName);
+$cmd .= " -httpd $vncJavaFiles" if ($vncJavaFiles);
+$cmd .= " -auth $xauthorityFile";
+$cmd .= " -geometry $geometry" if ($geometry);
+$cmd .= " -depth $depth" if ($depth);
+$cmd .= " -pixelformat $pixelformat" if ($pixelformat);
+$cmd .= " -rfbwait 30000";
+$cmd .= " -rfbauth $vncUserDir/passwd";
+$cmd .= " -rfbport $vncPort";
+$cmd .= " -fp $fontPath" if ($fontPath);
+$cmd .= " -pn";
+
+# Add color database stuff here, e.g.:
+#
+# $cmd .= " -co /usr/lib/X11/rgb";
+#
+
+foreach $arg (@ARGV) {
+    $cmd .= " " . &quotedString($arg);
+}
+$cmd .= " >> " . &quotedString($desktopLog) . " 2>&1";
+
+# Run $cmd and record the process ID.
+
+$pidFile = "$vncUserDir/$host:$displayNumber.pid";
+system("$cmd & echo \$! >$pidFile");
+
+# Give Xvnc a chance to start up
+
+sleep(3); 
+if ($fontPath ne $defFontPath) {
+    unless (kill 0, `cat $pidFile`) {
+        if ($fpArgSpecified) {
+	    warn "\nWARNING: The first attempt to start Xvnc failed, probably because the font\n";
+	    warn "path you specified using the -fp argument is incorrect.  Attempting to\n";
+	    warn "determine an appropriate font path for this system and restart Xvnc using\n";
+	    warn "that font path ...\n";
+        } else {
+	    warn "\nWARNING: The first attempt to start Xvnc failed, possibly because the font\n";
+	    warn "catalog is not properly configured.  Attempting to determine an appropriate\n";
+	    warn "font path for this system and restart Xvnc using that font path ...\n";
+        }
+	$cmd =~ s@-fp [^ ]+@@;
+	$cmd .= " -fp $defFontPath" if ($defFontPath);
+	system("$cmd & echo \$! >$pidFile");
+	sleep(3);
+    }
+}
+unless (kill 0, `cat $pidFile`) {
+    warn "Could not start Xvnc.\n\n";
+    open(LOG, "<$desktopLog");
+    while (<LOG>) { print; }
+    close(LOG);
+    die "\n";
+}
+
+warn "\nNew '$desktopName' desktop is $host:$displayNumber\n\n";
+
+# Create the user's xstartup script if necessary.
+
+if (!(-e "$vncUserDir/xstartup")) {
+    warn "Creating default startup script $vncUserDir/xstartup\n";
+    open(XSTARTUP, ">$vncUserDir/xstartup");
+    print XSTARTUP $defaultXStartup;
+    close(XSTARTUP);
+    chmod 0755, "$vncUserDir/xstartup";
+}
+
+# Run the X startup script.
+
+warn "Starting applications specified in $vncUserDir/xstartup\n";
+warn "Log file is $desktopLog\n\n";
+
+# If the unix domain socket exists then use that (DISPLAY=:n) otherwise use
+# TCP (DISPLAY=host:n)
+
+if (-e "/tmp/.X11-unix/X$displayNumber" ||
+    -e "/usr/spool/sockets/X11/$displayNumber")
+{
+    $ENV{DISPLAY}= ":$displayNumber";
+} else {
+    $ENV{DISPLAY}= "$host:$displayNumber";
+}
+$ENV{VNCDESKTOP}= $desktopName;
+
+system($exedir."vncconfig -iconic >> " . &quotedString($desktopLog) . " 2>&1 &");
+
+if ($opt{'-fg'}) {
+    system("$vncUserDir/xstartup >> " . &quotedString($desktopLog) . " 2>&1");
+    if (kill 0, `cat $pidFile`) {
+        $opt{'-kill'} = ':'.$displayNumber;
+        &Kill();
+    }
+} else {
+    if ($opt{'-autokill'}) {
+        system("($vncUserDir/xstartup; $0 -kill :$displayNumber) >> "
+            . &quotedString($desktopLog) . " 2>&1 &");
+    } else {
+        system("$vncUserDir/xstartup >> " . &quotedString($desktopLog)
+            . " 2>&1 &");
+    }
+}
+
+exit;
+
+
+###############################################################################
+#
+# CheckGeometryAndDepth simply makes sure that the geometry and depth values
+# are sensible.
+#
+
+sub CheckGeometryAndDepth
+{
+    if ($geometry =~ /^(\d+)x(\d+)$/) {
+	$width = $1; $height = $2;
+
+	if (($width<1) || ($height<1)) {
+	    die "$prog: geometry $geometry is invalid\n";
+	}
+
+	$geometry = "${width}x$height";
+    } else {
+	die "$prog: geometry $geometry is invalid\n";
+    }
+
+    if ($depth && (($depth < 8) || ($depth > 32))) {
+	die "Depth must be between 8 and 32\n";
+    }
+}
+
+
+#
+# GetDisplayNumber gets the lowest available display number.  A display number
+# n is taken if something is listening on the VNC server port (5900+n) or the
+# X server port (6000+n).
+#
+
+sub GetDisplayNumber
+{
+    foreach $n (1..99) {
+	if (&CheckDisplayNumber($n)) {
+	    return $n+0; # Bruce Mah's workaround for bug in perl 5.005_02
+	}
+    }
+    
+    die "$prog: no free display number on $host.\n";
+}
+
+
+#
+# CheckDisplayNumber checks if the given display number is available.  A
+# display number n is taken if something is listening on the VNC server port
+# (5900+n) or the X server port (6000+n).
+#
+
+sub CheckDisplayNumber
+{
+    local ($n) = @_;
+
+    socket(S, $AF_INET, $SOCK_STREAM, 0) || die "$prog: socket failed: $!\n";
+    eval 'setsockopt(S, &SOL_SOCKET, &SO_REUSEADDR, pack("l", 1))';
+    if (!bind(S, pack('S n x12', $AF_INET, 6000 + $n))) {
+	close(S);
+	return 0;
+    }
+    close(S);
+
+    socket(S, $AF_INET, $SOCK_STREAM, 0) || die "$prog: socket failed: $!\n";
+    eval 'setsockopt(S, &SOL_SOCKET, &SO_REUSEADDR, pack("l", 1))';
+    if (!bind(S, pack('S n x12', $AF_INET, 5900 + $n))) {
+	close(S);
+	return 0;
+    }
+    close(S);
+
+    if (-e "/tmp/.X$n-lock") {
+	warn "\nWarning: $host:$n is taken because of /tmp/.X$n-lock\n";
+	warn "Remove this file if there is no X server $host:$n\n";
+	return 0;
+    }
+
+    if (-e "/tmp/.X11-unix/X$n") {
+	warn "\nWarning: $host:$n is taken because of /tmp/.X11-unix/X$n\n";
+	warn "Remove this file if there is no X server $host:$n\n";
+	return 0;
+    }
+
+    if (-e "/usr/spool/sockets/X11/$n") {
+	warn("\nWarning: $host:$n is taken because of ".
+             "/usr/spool/sockets/X11/$n\n");
+	warn "Remove this file if there is no X server $host:$n\n";
+	return 0;
+    }
+
+    return 1;
+}
+
+
+#
+# GetXDisplayDefaults uses xdpyinfo to find out the geometry, depth and pixel
+# format of the current X display being used.  If successful, it sets the
+# options as appropriate so that the X VNC server will use the same settings
+# (minus an allowance for window manager decorations on the geometry).  Using
+# the same depth and pixel format means that the VNC server won't have to
+# translate pixels when the desktop is being viewed on this X display (for
+# TrueColor displays anyway).
+#
+
+sub GetXDisplayDefaults
+{
+    local (@lines, @matchlines, $width, $height, $defaultVisualId, $i,
+	   $red, $green, $blue);
+
+    $wmDecorationWidth = 4;	# a guess at typical size for window manager
+    $wmDecorationHeight = 24;	# decoration size
+
+    return if (!defined($ENV{DISPLAY}));
+
+    @lines = `xdpyinfo 2>/dev/null`;
+
+    return if ($? != 0);
+
+    @matchlines = grep(/dimensions/, @lines);
+    if (@matchlines) {
+	($width, $height) = ($matchlines[0] =~ /(\d+)x(\d+) pixels/);
+
+	$width -= $wmDecorationWidth;
+	$height -= $wmDecorationHeight;
+
+	$geometry = "${width}x$height";
+    }
+
+    @matchlines = grep(/default visual id/, @lines);
+    if (@matchlines) {
+	($defaultVisualId) = ($matchlines[0] =~ /id:\s+(\S+)/);
+
+	for ($i = 0; $i < @lines; $i++) {
+	    if ($lines[$i] =~ /^\s*visual id:\s+$defaultVisualId$/) {
+		if (($lines[$i+1] !~ /TrueColor/) ||
+		    ($lines[$i+2] !~ /depth/) ||
+		    ($lines[$i+4] !~ /red, green, blue masks/))
+		{
+		    return;
+		}
+		last;
+	    }
+	}
+
+	return if ($i >= @lines);
+
+	($depth) = ($lines[$i+2] =~ /depth:\s+(\d+)/);
+	($red,$green,$blue)
+	    = ($lines[$i+4]
+	       =~ /masks:\s+0x([0-9a-f]+), 0x([0-9a-f]+), 0x([0-9a-f]+)/);
+
+	$red = hex($red);
+	$green = hex($green);
+	$blue = hex($blue);
+
+	if ($red > $blue) {
+	    $red = int(log($red) / log(2)) - int(log($green) / log(2));
+	    $green = int(log($green) / log(2)) - int(log($blue) / log(2));
+	    $blue = int(log($blue) / log(2)) + 1;
+	    $pixelformat = "rgb$red$green$blue";
+	} else {
+	    $blue = int(log($blue) / log(2)) - int(log($green) / log(2));
+	    $green = int(log($green) / log(2)) - int(log($red) / log(2));
+	    $red = int(log($red) / log(2)) + 1;
+	    $pixelformat = "bgr$blue$green$red";
+	}
+    }
+}
+
+
+#
+# quotedString returns a string which yields the original string when parsed
+# by a shell.
+#
+
+sub quotedString
+{
+    local ($in) = @_;
+
+    $in =~ s/\'/\'\"\'\"\'/g;
+
+    return "'$in'";
+}
+
+
+#
+# removeSlashes turns slashes into underscores for use as a file name.
+#
+
+sub removeSlashes
+{
+    local ($in) = @_;
+
+    $in =~ s|/|_|g;
+
+    return "$in";
+}
+
+
+#
+# Usage
+#
+
+sub Usage
+{
+    die("\nusage: $prog [:<number>] [-name <desktop-name>] [-depth <depth>]\n".
+	"                 [-geometry <width>x<height>]\n".
+	"                 [-pixelformat rgbNNN|bgrNNN]\n".
+	"                 [-fp <font-path>]\n".
+	"                 [-cc <visual>]\n".
+	"                 [-fg]\n".
+	"                 [-autokill]\n".
+	"                 <Xvnc-options>...\n\n".
+	"       $prog -kill <X-display>\n\n".
+	"       $prog -list\n\n");
+}
+
+
+#
+# List
+#
+
+sub List
+{
+    opendir(dir, $vncUserDir);
+    my @filelist = readdir(dir);
+    closedir(dir);
+    print "\nTigerVNC server sessions:\n\n";
+    print "X DISPLAY #\tPROCESS ID\n";
+    foreach my $file (@filelist) {
+	if ($file =~ /$host:(\d+)$\.pid/) {
+	    print ":".$1."\t\t".`cat $vncUserDir/$file`;
+	}
+    }
+    exit 1;
+}
+
+
+#
+# Kill
+#
+
+sub Kill
+{
+    $opt{'-kill'} =~ s/(:\d+)\.\d+$/$1/; # e.g. turn :1.0 into :1
+
+    if ($opt{'-kill'} =~ /^:\d+$/) {
+	$pidFile = "$vncUserDir/$host$opt{'-kill'}.pid";
+    } else {
+	if ($opt{'-kill'} !~ /^$host:/) {
+	    die "\nCan't tell if $opt{'-kill'} is on $host\n".
+		"Use -kill :<number> instead\n\n";
+	}
+	$pidFile = "$vncUserDir/$opt{'-kill'}.pid";
+    }
+
+    if (! -r $pidFile) {
+	die "\nCan't find file $pidFile\n".
+	    "You'll have to kill the Xvnc process manually\n\n";
+    }
+
+    $SIG{'HUP'} = 'IGNORE';
+    chop($pid = `cat $pidFile`);
+    warn "Killing Xvnc process ID $pid\n";
+
+    if (kill 0, $pid) {
+	system("kill $pid");
+	sleep(1);
+	if (kill 0, $pid) {
+	    print "Xvnc seems to be deadlocked.  Kill the process manually and then re-run\n";
+	    print "    ".$0." -kill ".$opt{'-kill'}."\n";
+	    print "to clean up the socket files.\n";
+	    exit
+	}
+
+    } else {
+	warn "Xvnc process ID $pid already killed\n";
+	$opt{'-kill'} =~ s/://;
+    
+	if (-e "/tmp/.X11-unix/X$opt{'-kill'}") {
+	    print "Xvnc did not appear to shut down cleanly.";
+	    print " Removing /tmp/.X11-unix/X$opt{'-kill'}\n";
+	    unlink "/tmp/.X11-unix/X$opt{'-kill'}";
+	}
+	if (-e "/tmp/.X$opt{'-kill'}-lock") {
+	    print "Xvnc did not appear to shut down cleanly.";
+	    print " Removing /tmp/.X$opt{'-kill'}-lock\n";
+	    unlink "/tmp/.X$opt{'-kill'}-lock";
+	}
+    }
+
+    unlink $pidFile;
+    exit;
+}
+
+
+#
+# ParseOptions takes a list of possible options and a boolean indicating
+# whether the option has a value following, and sets up an associative array
+# %opt of the values of the options given on the command line. It removes all
+# the arguments it uses from @ARGV and returns them in @optArgs.
+#
+
+sub ParseOptions
+{
+    local (@optval) = @_;
+    local ($opt, @opts, %valFollows, @newargs);
+
+    while (@optval) {
+	$opt = shift(@optval);
+	push(@opts,$opt);
+	$valFollows{$opt} = shift(@optval);
+    }
+
+    @optArgs = ();
+    %opt = ();
+
+    arg: while (defined($arg = shift(@ARGV))) {
+	foreach $opt (@opts) {
+	    if ($arg eq $opt) {
+		push(@optArgs, $arg);
+		if ($valFollows{$opt}) {
+		    if (@ARGV == 0) {
+			&Usage();
+		    }
+		    $opt{$opt} = shift(@ARGV);
+		    push(@optArgs, $opt{$opt});
+		} else {
+		    $opt{$opt} = 1;
+		}
+		next arg;
+	    }
+	}
+	push(@newargs,$arg);
+    }
+
+    @ARGV = @newargs;
+}
+
+
+#
+# Routine to make sure we're operating in a sane environment.
+#
+
+sub SanityCheck
+{
+    local ($cmd);
+
+    #
+    # Get the program name
+    #
+
+    ($prog) = ($0 =~ m|([^/]+)$|);
+
+    #
+    # Check we have all the commands we'll need on the path.
+    #
+
+ cmd:
+    foreach $cmd ("uname") {
+	for (split(/:/,$ENV{PATH})) {
+	    if (-x "$_/$cmd") {
+		next cmd;
+	    }
+	}
+	die "$prog: couldn't find \"$cmd\" on your PATH.\n";
+    }
+    if (-x "/usr/X11R6/bin/xauth") {
+	$xauth = "/usr/X11R6/bin/xauth";
+    }
+    else {
+      cmd1:
+	foreach $cmd ("xauth") {
+	    for (split(/:/,$ENV{PATH})) {
+		if (-x "$_/$cmd") {
+		    next cmd1;
+		}
+	    }
+	    die "$prog: couldn't find \"$cmd\" on your PATH.\n";
+	}
+    }
+
+    if($exedir eq "") {
+      cmd2:
+	foreach $cmd ("Xvnc","vncpasswd") {
+	    for (split(/:/,$ENV{PATH})) {
+		if (-x "$_/$cmd") {
+		    $vncClasses = "$_/../vnc/classes";
+		    next cmd2;
+		}
+	    }
+	    die "$prog: couldn't find \"$cmd\" on your PATH.\n";
+	}
+    }
+    else {
+      cmd3:
+	foreach $cmd ($exedir."Xvnc",$exedir."vncpasswd") {
+	    for (split(/:/,$ENV{PATH})) {
+		if (-x "$cmd") {
+		    $vncClasses = $exedir."../vnc/classes";
+		    next cmd3;
+		}
+	    }
+	    die "$prog: couldn't find \"$cmd\".\n";
+	}
+    }
+
+    #
+    # Check the HOME environment variable is set
+    #
+
+    if (!defined($ENV{HOME})) {
+	die "$prog: The HOME environment variable is not set.\n";
+    }
+#    chdir($ENV{HOME});
+
+    #
+    # Find socket constants. 'use Socket' is a perl5-ism, so we wrap it in an
+    # eval, and if it fails we try 'require "sys/socket.ph"'.  If this fails,
+    # we just guess at the values.  If you find perl moaning here, just
+    # hard-code the values of AF_INET and SOCK_STREAM.  You can find these out
+    # for your platform by looking in /usr/include/sys/socket.h and related
+    # files.
+    #
+
+    chop($os = `uname`);
+    chop($osrev = `uname -r`);
+
+    eval 'use Socket';
+    if ($@) {
+	eval 'require "sys/socket.ph"';
+	if ($@) {
+	    if (($os eq "SunOS") && ($osrev !~ /^4/)) {
+		$AF_INET = 2;
+		$SOCK_STREAM = 2;
+	    } else {
+		$AF_INET = 2;
+		$SOCK_STREAM = 1;
+	    }
+	} else {
+	    $AF_INET = &AF_INET;
+	    $SOCK_STREAM = &SOCK_STREAM;
+	}
+    } else {
+	$AF_INET = &AF_INET;
+	$SOCK_STREAM = &SOCK_STREAM;
+    }
+}
diff --git a/roles/vncserver/templates/vncserver.ubuntu b/roles/vncserver/templates/vncserver.ubuntu
new file mode 100755
index 0000000000000000000000000000000000000000..4f814a5930b82b9ae2be225cdcd5ed1ca86c8c10
--- /dev/null
+++ b/roles/vncserver/templates/vncserver.ubuntu
@@ -0,0 +1,772 @@
+#!/usr/bin/perl
+#
+#  Copyright (C) 2004-2006,2008-2009 Ola Lundqvist <opal@debian.org>
+#  Copyright (C) 2002-2003 Constantin Kaplinsky.  All Rights Reserved.
+#  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
+#
+#  This 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 2 of the License, or
+#  (at your option) any later version.
+#
+#  This software 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 this software; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
+#  USA.
+#
+
+#
+# vncserver - wrapper script to start an X VNC server.
+#
+
+# This file was heavily edited by
+#              Ola Lundqvist <opal@debian.org>
+#               Marcus Brinkmann <Marcus.Brinkmann@ruhr-uni-bochum.de>
+# Clean option by Dirk Eddelbuettel <edd@debian.org>
+
+# Please report all errors to Debian and not to ORL.
+
+#
+# First make sure we're operating in a sane environment.
+#
+
+&SanityCheck();
+
+#
+# Global variables.  You may want to configure some of these for your site.
+#
+
+$geometry = "1024x768";
+$depth = 24;
+$desktopName = "X";
+if (-d "/usr/share/tightvnc-java") {
+    $vncClasses = "/usr/share/tightvnc-java";
+}
+$vncUserDir = "$ENV{HOME}/.vnc";
+#$fontPath = "unix/:7100";
+$authType = "-rfbauth $vncUserDir/passwd";
+
+# Here is another example of setting the font path:
+# $fontPath = "/usr/lib/X11/fonts/misc/,/usr/lib/X11/fonts/75dpi/";
+
+# X colors database path is optional, uncomment and edit to use:
+# $colorPath = "/usr/lib/X11/rgb";
+
+# You might wish to make your vnc directory under /tmp, to make sure
+# passwords are always kept on the local filesystem. To do that, just
+# uncomment the line below. Note that in this case Xtightvnc's .Xauthority
+# file will be searched in the same $vncUserDir directory by default,
+# and $ENV{HOME}/.vncstartup will be executed instead of usual
+# $vncUserDir/xstartup.
+#
+# $vncUserDir = "/tmp/$ENV{USER}-vnc";
+
+$defaultXStartup
+    = ("#!/bin/sh\n\n".
+       "xrdb \$HOME/.Xresources\n".
+       "xsetroot -solid grey\n".
+       "#x-terminal-emulator -geometry 80x24+10+10 -ls -title \"\$VNCDESKTOP Desktop\" &\n".
+       "#x-window-manager &\n".
+       "# Fix to make GNOME work\n".
+       "export XKL_XMODMAP_DISABLE=1\n".
+       "exec mate-session\n");
+
+$xauthorityFile = "$ENV{XAUTHORITY}";
+
+######## Adding configuration possibility ################
+$Config_file = "/etc/vnc.conf";
+&ReadConfigFile();
+$Config_file = "$ENV{HOME}/.vncrc";
+&ReadConfigFile();
+
+if (!$XFConfigPath) {
+  foreach ("/etc/X11/xorg.conf", "/etc/X11/XF86Config-4", "/etc/X11/XF86Config" ){
+      $XFConfigPath = $_;
+      last if ( -e $XFConfigPath );
+  }
+}
+if (!$fontPath) {
+  &ReadXFConfigFont;
+}
+if (!$fontPath) {
+  $fontPath = "/usr/share/fonts/X11/misc/,".
+              "/usr/share/fonts/X11/Type1/,".
+              "/usr/share/fonts/X11/75dpi/,".
+              "/usr/share/fonts/X11/100dpi/"
+}
+if (!$colorPath) {
+  &ReadXFConfigColor;
+}
+if (!$colorPath) {
+  foreach ("/etc/X11/rgb", "/usr/share/X11/rgb", "/usr/X11R6/lib/X11/rgb"){
+      $colorPath = $_;
+      last if ( -e "${colorPath}.txt" );
+  }
+}
+##########################################################
+
+$vncUserDirUnderTmp = ($vncUserDir =~ m|^/tmp/.+|) ? 1 : 0;
+$xstartup = ($vncUserDirUnderTmp) ?
+  "$ENV{HOME}/.vncstartup" : "$vncUserDir/xstartup";
+$xstartup = $vncStartup if ($vncStartup);
+unless ($xauthorityFile) {
+    if ($vncUserDirUnderTmp) {
+        $xauthorityFile = "$vncUserDir/.Xauthority";
+    } else {
+        $xauthorityFile = "$ENV{HOME}/.Xauthority";
+    }
+}
+
+chop($host = `uname -n`);
+
+
+# Check command line options
+
+&ParseOptions("-geometry",1,"-depth",1,"-pixelformat",1,"-name",1,"-kill",1,
+	      "-help",0,"-h",0,"--help",0,
+	      "-clean",0, "-fp",1,
+              "-alwaysshared",0, "-nevershared",0,
+              "-httpport",1,"-basehttpport",1);
+
+&Usage() if ($opt{'-help'} || $opt{'-h'} || $opt{'--help'});
+
+&Kill() if ($opt{'-kill'});
+
+$useClasses = 0;
+if (defined $vncClasses) {
+  if(! -d $vncClasses) {
+    die "VNC class files can not be found at $vncClasses.";
+  }
+  $useClasses = 1;
+}
+
+# Uncomment this line if you want default geometry, depth and pixelformat
+# to match the current X display:
+# &GetXDisplayDefaults();
+
+if ($opt{'-geometry'}) {
+    $geometry = $opt{'-geometry'};
+}
+if ($opt{'-depth'}) {
+    $depth = $opt{'-depth'};
+    $pixelformat = "";
+}
+if ($opt{'-pixelformat'}) {
+    $pixelformat = $opt{'-pixelformat'};
+}
+
+if ($opt{'-fp'}) {
+    @fontPathElements = split(/\s*,\s*/, "$opt{'-fp'}");
+
+    $fontPath = '';
+
+    foreach $i (0.."$#fontPathElements") {
+        $tempFontPath = $fontPathElements[$i];
+        if ($tempFontPath !~ m!^[^/]*/[^/]*:\d+$!) {
+            $tempFontPath =~ s/:unscaled$//;
+            if (-r "$tempFontPath/fonts.dir") {
+                $fontPath .= "$fontPathElements[$i],";
+            }
+        } else {
+            $fontPath .= "$fontPathElements[$i],";
+        }
+    }
+    chop $fontPath;
+}
+
+&CheckGeometryAndDepth();
+
+if ($opt{'-name'}) {
+    $desktopName = $opt{'-name'};
+}
+
+# Create the user's vnc directory if necessary.
+
+unless (-e $vncUserDir) {
+    unless (mkdir($vncUserDir, 0700)) {
+        die "$prog: Could not create $vncUserDir.\n";
+    }
+}
+($z,$z,$mode) = stat("$vncUserDir");
+if (!-d _ || !-o _ || ($vncUserDirUnderTmp && ($mode & 0777) != 0700)) {
+    die "$prog: Wrong type or access mode of $vncUserDir.\n";
+}
+
+# Make sure the user has a password.
+
+($z,$z,$mode) = stat("$vncUserDir/passwd");
+if (-e _ && (!-f _ || !-o _)) {
+    die "$prog: Wrong type or ownership on $vncUserDir/passwd.\n";
+}
+if (!-e _ || ($mode & 077) != 0) {
+    warn "\nYou will require a password to access your desktops.\n\n";
+    system("vncpasswd $vncUserDir/passwd");
+    if (($? & 0xFF00) != 0) {
+        exit 1;
+    }
+}
+
+# Find display number.
+
+if ((@ARGV > 0) && ($ARGV[0] =~ /^:(\d+)$/)) {
+    $displayNumber = $1;
+    shift(@ARGV);
+    unless (&CheckDisplayNumber($displayNumber)) {
+	die "A VNC server is already running as :$displayNumber\n";
+    }
+} elsif ((@ARGV > 0) && ($ARGV[0] !~ /^-/)) {
+    &Usage();
+} else {
+    $displayNumber = &GetDisplayNumber();
+}
+
+$vncPort = 5900 + $displayNumber;
+
+$desktopLog = "$vncUserDir/$host:$displayNumber.log";
+unlink($desktopLog);
+
+# Make an X server cookie - use as the seed the sum of the current time, our
+# PID and part of the encrypted form of the password.  Ideally we'd use
+# /dev/urandom, but that's only available on Linux.
+
+srand(time+$$+unpack("L",`cat $vncUserDir/passwd`));
+$cookie = "";
+for (1..16) {
+    $cookie .= sprintf("%02x", int(rand(256)));
+}
+
+system("xauth -f $xauthorityFile add $host:$displayNumber . $cookie");
+system("xauth -f $xauthorityFile add $host/unix:$displayNumber . $cookie"); 
+
+# Now start the X VNC Server
+
+$cmd = "Xtightvnc :$displayNumber";
+$cmd .= " -desktop " . &quotedString($desktopName);
+if ($useClasses) {
+  $cmd .= " -httpd $vncClasses";
+  print ("Found $vncClasses for http connections.\n");
+  if ($opt{'-httpport'}) {
+    $cmd .= " -httpport $opt{'-httpport'}";
+    print ("Listening to $opt{'-httpport'} for http connections.\n");
+  }
+  elsif ($opt{'-basehttpport'}) {
+    my $v = $opt{'-basehttpport'} + $displayNumber;
+    print ("Listening to $v for http connections.\n");
+    $cmd .= " -httpport $v";
+  }
+}
+$cmd .= " -auth $xauthorityFile";
+$cmd .= " -geometry $geometry" if ($geometry);
+$cmd .= " -depth $depth" if ($depth);
+$cmd .= " -pixelformat $pixelformat" if ($pixelformat);
+$cmd .= " -rfbwait 120000";
+$cmd .= " $authType";
+$cmd .= " -rfbport $vncPort";
+$cmd .= " -fp $fontPath" if ($fontPath);
+$cmd .= " -co $colorPath" if ($colorPath);
+$cmd .= " -alwaysshared" if ($opt{'-alwaysshared'});
+$cmd .= " -nevershared" if ($opt{'-nevershared'});
+
+foreach $arg (@ARGV) {
+    $cmd .= " " . &quotedString($arg);
+}
+$cmd .= " >> " . &quotedString($desktopLog) . " 2>&1";
+
+# Run $cmd and record the process ID.
+
+$pidFile = "$vncUserDir/$host:$displayNumber.pid";
+system("$cmd & echo \$! >$pidFile");
+
+# Give Xtightvnc a chance to start up
+
+sleep(1);
+unless (kill 0, `cat $pidFile`) {
+    warn "Couldn't start Xtightvnc; trying default font path.\n";
+    warn "Please set correct fontPath in the $prog script.\n";
+    $cmd =~ s@-fp [^ ]+@@;
+    system("$cmd & echo \$! >$pidFile");
+    sleep(1);
+}
+unless (kill 0, `cat $pidFile`) {
+    warn "Couldn't start Xtightvnc process.\n\n";
+    open(LOG, "<$desktopLog");
+    while (<LOG>) { print; }
+    close(LOG);
+    die "\n";
+}
+
+warn "\nNew '$desktopName' desktop is $host:$displayNumber\n\n";
+
+# Create the user's xstartup script if necessary.
+
+unless (-e "$xstartup") {
+    warn "Creating default startup script $xstartup\n";
+    open(XSTARTUP, ">$xstartup");
+    print XSTARTUP $defaultXStartup;
+    close(XSTARTUP);
+    chmod 0755, "$xstartup";
+}
+
+# Run the X startup script.
+
+warn "Starting applications specified in $xstartup\n";
+warn "Log file is $desktopLog\n\n";
+
+# If the unix domain socket exists then use that (DISPLAY=:n) otherwise use
+# TCP (DISPLAY=host:n)
+
+if (-e "/tmp/.X11-unix/X$displayNumber") {
+    $ENV{DISPLAY}= ":$displayNumber";
+} else {
+    $ENV{DISPLAY}= "$host:$displayNumber";
+}
+$ENV{VNCDESKTOP}= $desktopName;
+
+system("$xstartup >> " . &quotedString($desktopLog) . " 2>&1 &");
+
+exit;
+
+############################ Debian functions #################################
+# I thank Manoj for the code below.
+#
+# ReadConfigFile reads in a config file and sets variables according to it.
+#
+
+sub ReadConfigFile
+{
+  open(CONFIG, "$Config_file") || return;
+  my $lineno = 0;
+  while (<CONFIG>) {
+      chomp;
+      $lineno++;
+      s/\#.*//og;
+      next if /^\s*$/og;
+      $_ .= ";" unless /;\s*$/;
+      if (/^\s*([^=]+)\s*=\s*(\S.*)$/o) {
+          my $ret = eval "$1=$2";
+          if ($@) {
+              print STDERR "Error parsing config file $Config_file!\n";
+              print STDERR "$lineno:$_\n";
+          }
+      }
+  }
+}
+
+sub ReadXFConfigFont
+{
+  open(CONFIG, "$XFConfigPath") || return;
+  my $lineno = 0;
+  while (<CONFIG>) {
+      chomp;
+      $lineno++;
+      s/\#.*//og;
+      next if /^\s*$/og;
+      if (/^\s*FontPath\s*"(\S.*)"\s*$/o) {
+          $fontPath .= "," if $fontPath;
+          $fontPath .= $1;
+      }
+  }
+}
+
+sub ReadXFConfigColor
+{
+  open(CONFIG, "$XFConfigPath") || return;
+  my $lineno = 0;
+  while (<CONFIG> && !$colorPath) {
+      chomp;
+      $lineno++;
+      s/\#.*//og;
+      next if /^\s*$/og;
+      if (/^\s*RgbPath\s*"(\S.*)"\s*$/o) {
+          $colorPath = $1;
+      }
+  }
+}
+
+
+########## End of debian functions ###########
+
+###############################################################################
+#
+# CheckGeometryAndDepth simply makes sure that the geometry and depth values
+# are sensible.
+#
+
+sub CheckGeometryAndDepth
+{
+    if ($geometry =~ /^(\d+)x(\d+)$/) {
+	$width = $1; $height = $2;
+
+	if (($width<1) || ($height<1)) {
+	    die "$prog: geometry $geometry is invalid\n";
+	}
+
+	while (($width % 4)!=0) {
+	    $width = $width + 1;
+	}
+
+	while (($height % 2)!=0) {
+	    $height = $height + 1;
+	}
+
+	$geometry = "${width}x$height";
+    } else {
+	die "$prog: geometry $geometry is invalid\n";
+    }
+
+    if (($depth < 8) || ($depth > 32)) {
+	die "Depth must be between 8 and 32\n";
+    }
+}
+
+
+#
+# GetDisplayNumber gets the lowest available display number.  A display number
+# n is taken if something is listening on the VNC server port (5900+n) or the
+# X server port (6000+n).
+#
+
+sub GetDisplayNumber
+{
+    foreach $n (1..99) {
+	if (&CheckDisplayNumber($n)) {
+	    return $n+0; # Bruce Mah's workaround for bug in perl 5.005_02
+	}
+    }
+    
+    die "$prog: no free display number on $host.\n";
+}
+
+
+#
+# CheckDisplayNumber checks if the given display number is available.  A
+# display number n is taken if something is listening on the VNC server port
+# (5900+n) or the X server port (6000+n).
+#
+
+sub CheckDisplayNumber
+{
+    local ($n) = @_;
+
+    socket(S, $AF_INET, $SOCK_STREAM, 0) || die "$prog: socket failed: $!\n";
+    eval 'setsockopt(S, &SOL_SOCKET, &SO_REUSEADDR, pack("l", 1))';
+    #unless (bind(S, pack('S n x12', $AF_INET, 6000 + $n))) {
+    unless (bind(S, sockaddr_in(6000 + $n, &INADDR_ANY))) {
+	close(S);
+	return 0;
+    }
+    close(S);
+
+    socket(S, $AF_INET, $SOCK_STREAM, 0) || die "$prog: socket failed: $!\n";
+    eval 'setsockopt(S, &SOL_SOCKET, &SO_REUSEADDR, pack("l", 1))';
+    #unless (bind(S, pack('S n x12', $AF_INET, 5900 + $n))) {
+    unless (bind(S, sockaddr_in(5900 + $n, &INADDR_ANY))) {
+	close(S);
+	return 0;
+    }
+    close(S);
+
+    if (-e "/tmp/.X$n-lock") {
+	warn "\nWarning: $host:$n is taken because of /tmp/.X$n-lock\n";
+	warn "Remove this file if there is no X server $host:$n\n";
+	return 0;
+    }
+
+    if (-e "/tmp/.X11-unix/X$n") {
+	warn "\nWarning: $host:$n is taken because of /tmp/.X11-unix/X$n\n";
+	warn "Remove this file if there is no X server $host:$n\n";
+	return 0;
+    }
+
+    return 1;
+}
+
+
+#
+# GetXDisplayDefaults uses xdpyinfo to find out the geometry, depth and pixel
+# format of the current X display being used.  If successful, it sets the
+# options as appropriate so that the X VNC server will use the same settings
+# (minus an allowance for window manager decorations on the geometry).  Using
+# the same depth and pixel format means that the VNC server won't have to
+# translate pixels when the desktop is being viewed on this X display (for
+# TrueColor displays anyway).
+#
+
+sub GetXDisplayDefaults
+{
+    local (@lines, @matchlines, $width, $height, $defaultVisualId, $i,
+	   $red, $green, $blue);
+
+    $wmDecorationWidth = 4;	# a guess at typical size for window manager
+    $wmDecorationHeight = 24;	# decoration size
+
+    return unless (defined($ENV{DISPLAY}));
+
+    @lines = `xdpyinfo 2>/dev/null`;
+
+    return if ($? != 0);
+
+    @matchlines = grep(/dimensions/, @lines);
+    if (@matchlines) {
+	($width, $height) = ($matchlines[0] =~ /(\d+)x(\d+) pixels/);
+
+	$width -= $wmDecorationWidth;
+	$height -= $wmDecorationHeight;
+
+	$geometry = "${width}x$height";
+    }
+
+    @matchlines = grep(/default visual id/, @lines);
+    if (@matchlines) {
+	($defaultVisualId) = ($matchlines[0] =~ /id:\s+(\S+)/);
+
+	for ($i = 0; $i < @lines; $i++) {
+	    if ($lines[$i] =~ /^\s*visual id:\s+$defaultVisualId$/) {
+		if (($lines[$i+1] !~ /TrueColor/) ||
+		    ($lines[$i+2] !~ /depth/) ||
+		    ($lines[$i+4] !~ /red, green, blue masks/))
+		{
+		    return;
+		}
+		last;
+	    }
+	}
+
+	return if ($i >= @lines);
+
+	($depth) = ($lines[$i+2] =~ /depth:\s+(\d+)/);
+	($red,$green,$blue)
+	    = ($lines[$i+4]
+	       =~ /masks:\s+0x([0-9a-f]+), 0x([0-9a-f]+), 0x([0-9a-f]+)/);
+
+	$red = hex($red);
+	$green = hex($green);
+	$blue = hex($blue);
+
+	if ($red > $blue) {
+	    $red = int(log($red) / log(2)) - int(log($green) / log(2));
+	    $green = int(log($green) / log(2)) - int(log($blue) / log(2));
+	    $blue = int(log($blue) / log(2)) + 1;
+	    $pixelformat = "rgb$red$green$blue";
+	} else {
+	    $blue = int(log($blue) / log(2)) - int(log($green) / log(2));
+	    $green = int(log($green) / log(2)) - int(log($red) / log(2));
+	    $red = int(log($red) / log(2)) + 1;
+	    $pixelformat = "bgr$blue$green$red";
+	}
+    }
+}
+
+
+#
+# quotedString returns a string which yields the original string when parsed
+# by a shell.
+#
+
+sub quotedString
+{
+    local ($in) = @_;
+
+    $in =~ s/\'/\'\"\'\"\'/g;
+
+    return "'$in'";
+}
+
+
+#
+# removeSlashes turns slashes into underscores for use as a file name.
+#
+
+sub removeSlashes
+{
+    local ($in) = @_;
+
+    $in =~ s|/|_|g;
+
+    return "$in";
+}
+
+
+#
+# Usage
+#
+
+sub Usage
+{
+    die("TightVNC Server version 1.3.9\n".
+	"\n".
+	"Usage: $prog [<OPTIONS>] [:<DISPLAY#>]\n".
+	"       $prog -kill :<DISPLAY#>\n".
+	"\n".
+	"<OPTIONS> are Xtightvnc options, or:\n".
+	"\n".
+	"        -name <DESKTOP-NAME>\n".
+	"        -depth <DEPTH>\n".
+	"        -geometry <WIDTH>x<HEIGHT>\n".
+        "        -httpport number\n".
+        "        -basehttpport number\n".
+        "        -alwaysshared\n".
+        "        -nevershared\n".
+	"        -pixelformat rgb<NNN>\n".
+	"        -pixelformat bgr<NNN>\n".
+	"\n".
+	"See vncserver and Xtightvnc manual pages for more information.\n");
+}
+
+
+#
+# Kill
+#
+
+sub Kill
+{
+    $opt{'-kill'} =~ s/(:\d+)\.\d+$/$1/; # e.g. turn :1.0 into :1
+
+    if ($opt{'-kill'} =~ /^:\d+$/) {
+	$pidFile = "$vncUserDir/$host$opt{'-kill'}.pid";
+    } else {
+	if ($opt{'-kill'} !~ /^$host:/) {
+	    die "\nCan't tell if $opt{'-kill'} is on $host\n".
+		"Use -kill :<number> instead\n\n";
+	}
+	$pidFile = "$vncUserDir/$opt{'-kill'}.pid";
+    }
+
+    unless (-r $pidFile) {
+	die "\nCan't find file $pidFile\n".
+	    "You'll have to kill the Xtightvnc process manually\n\n";
+    }
+
+    $SIG{'HUP'} = 'IGNORE';
+    chop($pid = `cat $pidFile`);
+    warn "Killing Xtightvnc process ID $pid\n";
+    system("kill $pid");
+    unlink $pidFile;
+
+    ## If option -clean is given, also remove the logfile
+    unlink "$vncUserDir/$host$opt{'-kill'}.log" if ($opt{'-clean'});
+
+    exit;
+}
+
+
+#
+# ParseOptions takes a list of possible options and a boolean indicating
+# whether the option has a value following, and sets up an associative array
+# %opt of the values of the options given on the command line. It removes all
+# the arguments it uses from @ARGV and returns them in @optArgs.
+#
+
+sub ParseOptions
+{
+    local (@optval) = @_;
+    local ($opt, @opts, %valFollows, @newargs);
+
+    while (@optval) {
+	$opt = shift(@optval);
+	push(@opts,$opt);
+	$valFollows{$opt} = shift(@optval);
+    }
+
+    @optArgs = ();
+    %opt = ();
+
+    arg: while (defined($arg = shift(@ARGV))) {
+	foreach $opt (@opts) {
+	    if ($arg eq $opt) {
+		push(@optArgs, $arg);
+		if ($valFollows{$opt}) {
+		    if (@ARGV == 0) {
+			&Usage();
+		    }
+		    $opt{$opt} = shift(@ARGV);
+		    push(@optArgs, $opt{$opt});
+		} else {
+		    $opt{$opt} = 1;
+		}
+		next arg;
+	    }
+	}
+	push(@newargs,$arg);
+    }
+
+    @ARGV = @newargs;
+}
+
+
+#
+# Routine to make sure we're operating in a sane environment.
+#
+
+sub SanityCheck
+{
+    local ($cmd);
+
+    #
+    # Get the program name
+    #
+
+    ($prog) = ($0 =~ m|([^/]+)$|);
+
+    #
+    # Check we have all the commands we'll need on the path.
+    #
+
+ cmd:
+    foreach $cmd ("uname","xauth","Xtightvnc","vncpasswd") {
+	for (split(/:/,$ENV{PATH})) {
+	    if (-x "$_/$cmd") {
+		next cmd;
+	    }
+	}
+	die "$prog: couldn't find \"$cmd\" on your PATH.\n";
+    }
+
+    #
+    # Check the HOME and USER environment variables are both set.
+    #
+
+    unless (defined($ENV{HOME})) {
+	die "$prog: The HOME environment variable is not set.\n";
+    }
+    unless (defined($ENV{USER})) {
+	die "$prog: The USER environment variable is not set.\n";
+    }
+
+    #
+    # Find socket constants. 'use Socket' is a perl5-ism, so we wrap it in an
+    # eval, and if it fails we try 'require "sys/socket.ph"'.  If this fails,
+    # we just guess at the values.  If you find perl moaning here, just
+    # hard-code the values of AF_INET and SOCK_STREAM.  You can find these out
+    # for your platform by looking in /usr/include/sys/socket.h and related
+    # files.
+    #
+
+    chop($os = `uname`);
+    chop($osrev = `uname -r`);
+
+    eval 'use Socket';
+    if ($@) {
+	eval 'require "sys/socket.ph"';
+	if ($@) {
+	    if (($os eq "SunOS") && ($osrev !~ /^4/)) {
+		$AF_INET = 2;
+		$SOCK_STREAM = 2;
+	    } else {
+		$AF_INET = 2;
+		$SOCK_STREAM = 1;
+	    }
+	} else {
+	    $AF_INET = &AF_INET;
+	    $SOCK_STREAM = &SOCK_STREAM;
+	}
+    } else {
+	$AF_INET = &AF_INET;
+	$SOCK_STREAM = &SOCK_STREAM;
+    }
+}
diff --git a/roles/vncserver/vars/CentOS_7_x86_64.yml b/roles/vncserver/vars/CentOS_7_x86_64.yml
index a32cb14e36f1f43d0c50c2dc3aeacb6e5b1562c7..0880aa2776c71ada625cd7f9b36dd9e5c57cf042 100644
--- a/roles/vncserver/vars/CentOS_7_x86_64.yml
+++ b/roles/vncserver/vars/CentOS_7_x86_64.yml
@@ -1,8 +1,6 @@
 ---
  system_packages:
-   - "@Desktop"
    - tigervnc-server
-   - "@xfce"
    - libXcomposite
    - libXdamage
    - mesa-libEGL
@@ -12,5 +10,11 @@
    - graphite2
    - xterm
    - libpng
-   - "@mate-desktop-environment"
-   #- "@MATE Desktop"
+   - xorg-x11-fonts-100dpi
+   - xorg-x11-fonts-75dpi
+   - xorg-x11-fonts-misc
+
+ system_group_packages:
+   - "mate-desktop-environment"
+   - "graphical-server-environment"
+
diff --git a/roles/vncserver/vars/Ubuntu_x86_64.yml b/roles/vncserver/vars/Ubuntu_x86_64.yml
index 780918f1c38e3ab65fa0f681010a4b103e1ee15b..3b5b3eb4a3ac0798fa1f8973c61812f5afd0defd 100644
--- a/roles/vncserver/vars/Ubuntu_x86_64.yml
+++ b/roles/vncserver/vars/Ubuntu_x86_64.yml
@@ -1,5 +1,6 @@
 ---
  system_packages:
    - tightvncserver
-   - xfce4-session
-   - xfwm4
+   - ubuntu-mate-desktop
+#   - xfce4-session
+#   - xfwm4