diff --git a/.cockpit.metadata b/.cockpit.metadata
index a9b4ccb..e89eb46 100644
--- a/.cockpit.metadata
+++ b/.cockpit.metadata
@@ -1 +1 @@
-de32b6dbb99ebb2edfc1223a653935e1daa83f3c SOURCES/cockpit-0.93.tar.xz
+c188051bfac8fc5b7b50f7ad25ba16972584138a SOURCES/cockpit-0.96.tar.xz
diff --git a/.gitignore b/.gitignore
index 4a35e14..b75a0cb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-SOURCES/cockpit-0.93.tar.xz
+SOURCES/cockpit-0.96.tar.xz
diff --git a/SOURCES/0001-test-Fix-selenium-test.patch b/SOURCES/0001-test-Fix-selenium-test.patch
new file mode 100644
index 0000000..ba0cd71
--- /dev/null
+++ b/SOURCES/0001-test-Fix-selenium-test.patch
@@ -0,0 +1,110 @@
+From 0a1baf5a3c9eda9a827cbb69a3bb096983baf359 Mon Sep 17 00:00:00 2001
+From: Jan Scotka <jscotka@redhat.com>
+Date: Thu, 3 Mar 2016 16:40:19 +0100
+Subject: [PATCH] test: Fix selenium test
+
+We shouldn't assume that we're the only ones working in /tmp during
+the tests, so take a bit more care with the filenames we choose.
+
+Also:
+ - Handle exceptions in avocado tests while fetching results
+ - Limit length of selenium debug output
+
+Reviewed-by: Dominik Perpeet <dperpeet@redhat.com>
+---
+ test/avocado/run-tests         | 13 +++++++++++--
+ test/avocado/selenium-login.py | 31 +++++++++++++++++--------------
+ test/avocado/seleniumlib.py    |  3 ++-
+ 3 files changed, 30 insertions(+), 17 deletions(-)
+
+diff --git a/test/avocado/run-tests b/test/avocado/run-tests
+index cc72fb1..e35b7e5 100755
+--- a/test/avocado/run-tests
++++ b/test/avocado/run-tests
+@@ -55,7 +55,12 @@ def prepare_avocado_tests(machine):
+     machine.upload([os.path.join(machine.test_dir, "avocado")], machine_test_dir)
+ 
+ def tap_output(machine):
+-    json_info = json.loads(machine.execute(command="cat " + os.path.join(avocado_results_dir, "latest/results.json"), quiet=True))
++    try:
++        json_info = json.loads(machine.execute(command="cat " + os.path.join(avocado_results_dir, "latest/results.json"), quiet=True))
++    except Exception as e:
++        print "ERROR: Unable to fetch JSON from remote machine:", os.path.join(avocado_results_dir, "latest/results.json")
++        print e
++        return None
+     print "\nTAP output -------------------------"
+     print "1..%s" % len(json_info['tests'])
+     counter = 1
+@@ -67,7 +72,11 @@ def tap_output(machine):
+         print "# ----------------------------------------------------------------------"
+         print "# %s (time %d secs)" % (test_name, test_time)
+         print "#"
+-        print machine.execute(command="cat " + test_log, quiet=True)
++        try:
++            print machine.execute(command="cat " + test_log, quiet=True)
++        except Exception as e:
++            print "ERROR: Unable to fetch testlog from remote machine:", test_log
++            print e
+         print "# TEST LOG END -------"
+         if test_status == 'PASS':
+             print "ok %s %s (time %d secs)" % (counter, test_name, test_time)
+diff --git a/test/avocado/selenium-login.py b/test/avocado/selenium-login.py
+index 29c4404..1e9e081 100755
+--- a/test/avocado/selenium-login.py
++++ b/test/avocado/selenium-login.py
+@@ -174,20 +174,23 @@ class BasicTestSuite(SeleniumTest):
+         self.wait_frame("terminal")
+         self.wait_id('terminal')
+         terminal = self.wait_xpath("//*[@class='terminal']")
+-        self.send_keys(terminal, "touch /tmp/testabc\n", clear=False)
+-        self.wait_text("touch /tmp/testabc", user, element="div")
+-        self.send_keys(terminal, "touch /tmp/testabd\n", clear=False)
+-        self.wait_text("touch /tmp/testabd",user, element="div")
+-        self.send_keys(terminal, "ls /tmp/test*\n", clear=False)
+-        self.wait_text("ls /tmp/test*",'/tmp/testabc /tmp/testabd', element="div")
+-        process.run("ls /tmp/testabc", shell=True)
+-        process.run("ls /tmp/testabd", shell=True)
+-        self.send_keys(terminal, "rm /tmp/testabc /tmp/testabd\n", clear=False)
+-        self.wait_text("rm /tmp/testabc /tmp/testabd",user, element="div")
+-        self.send_keys(terminal, "ls /tmp/test*\n", clear=False)
+-        self.wait_text("ls /tmp/test*",'cannot access', element="div")
+-        process.run("ls /tmp/testabc |wc -l |grep 0", shell=True)
+-        process.run("ls /tmp/testabd |wc -l |grep 0", shell=True)
++        prefix = "/tmp/cockpitrndadr/"
++        self.send_keys(terminal, "mkdir {0}\n".format(prefix), clear=False)
++        self.wait_text("mkdir {0}".format(prefix), user, element="div")
++        self.send_keys(terminal, "touch {0}abc\n".format(prefix), clear=False)
++        self.wait_text("touch {0}abc".format(prefix), user, element="div")
++        self.send_keys(terminal, "touch {0}abd\n".format(prefix), clear=False)
++        self.wait_text("touch {0}abd".format(prefix), user, element="div")
++        self.send_keys(terminal, "ls {0}*\n".format(prefix), clear=False)
++        self.wait_text("ls {0}*".format(prefix), '{0}abc'.format(prefix), element="div")
++        process.run("ls {0}abc".format(prefix), shell=True)
++        process.run("ls {0}abd".format(prefix), shell=True)
++        self.send_keys(terminal, "rm {0}abc {0}abd\n".format(prefix), clear=False)
++        self.wait_text("rm {0}abc {0}abd".format(prefix), user, element="div")
++        self.send_keys(terminal, "ls {0}*\n".format(prefix), clear=False)
++        self.wait_text("ls {0}*".format(prefix), 'cannot access', element="div")
++        process.run("ls {0}abc |wc -l |grep 0".format(prefix), shell=True)
++        process.run("ls {0}abd |wc -l |grep 0".format(prefix), shell=True)
+         self.mainframe()
+         self.error=False
+ 
+diff --git a/test/avocado/seleniumlib.py b/test/avocado/seleniumlib.py
+index 8d99cd3..e8e05f9 100755
+--- a/test/avocado/seleniumlib.py
++++ b/test/avocado/seleniumlib.py
+@@ -111,8 +111,9 @@ class SeleniumTest(Test):
+                 self.log.info('ERR: Unable to close WEBdriver: {0}'.format(e))
+ 
+     def get_debug_logs(self, logs=['browser','driver','client','server']):
++        max_line_log_count = 10
+         for log in logs:
+-            receivedlog = self.driver.get_log(log)
++            receivedlog = [x for x in self.driver.get_log(log)][-max_line_log_count:]
+             if receivedlog:
+                 self.log.info(">>>>> " + log)
+                 for line in receivedlog:
+-- 
+1.8.3.1
+
diff --git a/SOURCES/0001-ws-Recover-from-interruptions-during-read.patch b/SOURCES/0001-ws-Recover-from-interruptions-during-read.patch
deleted file mode 100644
index 2e698a3..0000000
--- a/SOURCES/0001-ws-Recover-from-interruptions-during-read.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-From 0a0250e8118c47ced529772758d49d6c5a60924f Mon Sep 17 00:00:00 2001
-From: Dominik Perpeet <dperpeet@redhat.com>
-Date: Mon, 1 Feb 2016 13:49:59 +0100
-Subject: [PATCH] ws: Recover from interruptions during read
-
-Reading crucial information needs to recover from interrupted and
-partial reads.
-
-Closes #3650
-Reviewed-by: Stef Walter <stefw@redhat.com>
----
- src/ws/cockpitauth.c | 18 +++++++++++++++++-
- 1 file changed, 17 insertions(+), 1 deletion(-)
-
-diff --git a/src/ws/cockpitauth.c b/src/ws/cockpitauth.c
-index f8f2f7d..e26d2a0 100644
---- a/src/ws/cockpitauth.c
-+++ b/src/ws/cockpitauth.c
-@@ -155,12 +155,28 @@ static void
- cockpit_auth_init (CockpitAuth *self)
- {
-   gint fd;
-+  gint read_bytes;
-+  gint read_result;
- 
-   self->key = g_byte_array_new ();
-   g_byte_array_set_size (self->key, 128);
-   fd = g_open ("/dev/urandom", O_RDONLY, 0);
--  if (fd < 0 || read (fd, self->key->data, 128) != 128)
-+  if (fd < 0)
-     g_error ("couldn't read random key, startup aborted");
-+  read_bytes = 0;
-+  do
-+    {
-+      errno = 0;
-+      read_result = read (fd, self->key->data + read_bytes, self->key->len - read_bytes);
-+      if (read_result <= 0)
-+        {
-+          if (errno == EAGAIN || errno == EINTR)
-+              continue;
-+          g_error ("couldn't read random key, startup aborted");
-+        }
-+      read_bytes += read_result;
-+    }
-+  while (read_bytes < self->key->len);
-   close (fd);
- 
-   self->authenticated = g_hash_table_new_full (g_str_hash, g_str_equal,
--- 
-2.4.3
-
diff --git a/SOURCES/0002-session-Make-sure-we-set-path-in-cockpit-session.patch b/SOURCES/0002-session-Make-sure-we-set-path-in-cockpit-session.patch
deleted file mode 100644
index ea24d2e..0000000
--- a/SOURCES/0002-session-Make-sure-we-set-path-in-cockpit-session.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From 8c1908035c919da58d29fab87b42126754f84405 Mon Sep 17 00:00:00 2001
-From: petervo <petervo@redhat.com>
-Date: Wed, 10 Feb 2016 02:29:00 -0800
-Subject: [PATCH] session: Make sure we set path in cockpit-session
-
-Reviewed-by: Marius Vollmer <marius.vollmer@redhat.com>
----
- src/ws/session.c | 7 ++++++-
- 1 file changed, 6 insertions(+), 1 deletion(-)
-
-diff --git a/src/ws/session.c b/src/ws/session.c
-index e877f15..618ca2e 100644
---- a/src/ws/session.c
-+++ b/src/ws/session.c
-@@ -56,6 +56,7 @@
- #define MAX_BUFFER 64 * 1024
- #define AUTH_FD 3
- #define EX 127
-+#define DEFAULT_PATH "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- 
- static struct passwd *pwd;
- const char *rhost;
-@@ -898,6 +899,7 @@ static const char *env_names[] = {
-   "G_DEBUG",
-   "G_MESSAGES_DEBUG",
-   "G_SLICE",
-+  "PATH",
-   NULL
- };
- 
-@@ -910,6 +912,9 @@ save_environment (void)
-   const char *value;
-   int i, j;
- 
-+  /* Force save our default path */
-+  setenv ("PATH", DEFAULT_PATH, 1);
-+
-   for (i = 0, j = 0; env_names[i] != NULL; i++)
-     {
-       value = getenv (env_names[i]);
-@@ -957,7 +962,7 @@ main (int argc,
-         }
- 
-       /* set a minimal environment */
--      setenv ("PATH", "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", 1);
-+      setenv ("PATH", DEFAULT_PATH, 1);
- 
-       if (setgid (0) != 0 || setuid (0) != 0)
-         err (1, "couldn't switch permissions correctly");
--- 
-1.8.3.1
-
diff --git a/SOURCES/0003-bridge-Set-a-PATH-if-none-is-set.patch b/SOURCES/0003-bridge-Set-a-PATH-if-none-is-set.patch
deleted file mode 100644
index 0b4c5da..0000000
--- a/SOURCES/0003-bridge-Set-a-PATH-if-none-is-set.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From e87b1e53eb5c0577299118f82956caa757ef81de Mon Sep 17 00:00:00 2001
-From: petervo <petervo@redhat.com>
-Date: Wed, 10 Feb 2016 02:38:20 -0800
-Subject: [PATCH] bridge: Set a PATH if none is set
-
-Closes #3723
-Reviewed-by: Marius Vollmer <marius.vollmer@redhat.com>
----
- src/bridge/cockpitbridge.c | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/src/bridge/cockpitbridge.c b/src/bridge/cockpitbridge.c
-index 531ecce..cb244f5 100644
---- a/src/bridge/cockpitbridge.c
-+++ b/src/bridge/cockpitbridge.c
-@@ -302,6 +302,9 @@ cockpit_bridge_new (CockpitTransport *transport,
-                          "init-received", init_received,
-                          NULL);
- 
-+  /* Set a path if nothing is set */
-+  g_setenv ("PATH", "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", 0);
-+
-   for (i = 0; payload_types[i].name != NULL; i++)
-     {
-       cockpit_bridge_add_payload (bridge, payload_types[i].name,
--- 
-1.8.3.1
-
diff --git a/SPECS/cockpit.spec b/SPECS/cockpit.spec
index f4c78e6..08d8fba 100644
--- a/SPECS/cockpit.spec
+++ b/SPECS/cockpit.spec
@@ -4,8 +4,8 @@
 #
 
 %define branding auto
-%define tag 0.93
-%define rev 3
+%define tag 0.96
+%define rev 2
 
 %if %{defined gitcommit}
 %define extra_flags CFLAGS='-O2 -Wall -Werror -fPIC -g -DWITH_DEBUG'
@@ -41,9 +41,7 @@ Source0:        cockpit-%{version}.tar.gz
 Source0:        https://github.com/cockpit-project/cockpit/releases/download/%{version}/cockpit-%{version}.tar.xz
 %endif
 
-Patch1:         0001-ws-Recover-from-interruptions-during-read.patch
-Patch2:	        0002-session-Make-sure-we-set-path-in-cockpit-session.patch
-Patch3:	        0003-bridge-Set-a-PATH-if-none-is-set.patch
+Patch1:		0001-test-Fix-selenium-test.patch
 
 BuildRequires: pkgconfig(gio-unix-2.0)
 BuildRequires: pkgconfig(json-glib-1.0)
@@ -151,8 +149,6 @@ The Cockpit Web Service listens on the network, and authenticates users.
 %prep
 %setup -q
 %patch1 -p1
-%patch2 -p1
-%patch3 -p1
 
 %build
 exec 2>&1
@@ -178,9 +174,6 @@ install -p -m 644 tools/cockpit.pam $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/cockpit
 rm -f %{buildroot}/%{_libdir}/cockpit/*.so
 install -p -m 644 AUTHORS COPYING README.md %{buildroot}%{_docdir}/%{name}/
 
-# This is not yet packaged
-rm -rf %{buildroot}%{_datadir}/%{name}/registry
-
 # On RHEL we don't yet show options for changing language
 %if 0%{?rhel}
 echo '{ "linguas": null, "machine-limit": 5 }' > %{buildroot}%{_datadir}/%{name}/shell/override.json
@@ -234,8 +227,15 @@ touch docker.list
 %ifarch x86_64
 echo '%dir %{_datadir}/%{name}/kubernetes' > kubernetes.list
 find %{buildroot}%{_datadir}/%{name}/kubernetes -type f >> kubernetes.list
+%if %{defined gitcommit}
+%else
+mv %{buildroot}/%{_datadir}/%{name}/registry/manifest.json %{buildroot}/%{_datadir}/%{name}/registry/manifest.disabled
+%endif
+echo '%dir %{_datadir}/%{name}/registry' >> kubernetes.list
+find %{buildroot}%{_datadir}/%{name}/registry -type f >> kubernetes.list
 %else
 rm -rf %{buildroot}/%{_datadir}/%{name}/kubernetes
+rm -rf %{buildroot}/%{_datadir}/%{name}/registry
 touch kubernetes.list
 %endif
 
@@ -252,6 +252,10 @@ rm -rf %{buildroot}/usr/src/debug
 cat subscriptions.list sosreport.list networkmanager.list >> shell.list
 %endif
 
+# dwz has trouble with the go binaries
+# https://fedoraproject.org/wiki/PackagingDrafts/Go
+%global _dwz_low_mem_die_limit 0
+
 # Only strip out debug info in non wip builds
 %if %{defined gitcommit}
 %define find_debug_info %{nil}
@@ -373,10 +377,10 @@ The Cockpit component for managing storage.  This package uses Storaged.
 
 %package ostree
 Summary: Cockpit user interface for rpm-ostree
-%if 0%{?rhel}
-Requires: rpm-ostree-client >= 2015.11-1
-%else
+%if 0%{?fedora} > 0 && 0%{?fedora} < 24
 Requires: rpm-ostree >= 2015.10-1
+%else
+Requires: /usr/libexec/rpm-ostreed
 %endif
 
 %description ostree
@@ -441,12 +445,17 @@ This package is not yet complete.
 %package kubernetes
 Summary: Cockpit user interface for Kubernetes cluster
 Requires: /usr/bin/kubectl
+Requires: %{name}-shell = %{version}-%{release}
+BuildRequires: golang-bin
+BuildRequires: golang-src
 
 %description kubernetes
 The Cockpit components for visualizing and configuring a Kubernetes
 cluster. Installed on the Kubernetes master. This package is not yet complete.
 
 %files kubernetes -f kubernetes.list
+%{_libexecdir}/cockpit-kube-auth
+%{_libexecdir}/cockpit-kube-launch
 
 %endif
 
@@ -463,12 +472,22 @@ pulls in some necessary packages via dependencies.
 %files test-assets
 %{_datadir}/%{name}/playground
 %{_datadir}/cockpit-test-assets
-%{_unitdir}/cockpit-testing.service
-%{_unitdir}/cockpit-testing.socket
 
 %endif
 
 %changelog
+* Thu Mar 10 2016 Dominik Perpeet <dperpeet@redhat.com> - 0.96-2
+- Fix selenium tests
+- Fix issue with dwz / go binaries in packages
+
+* Thu Mar 3 2016 Dominik Perpeet <dperpeet@redhat.com> - 0.96-1
+- Update to 0.96 release
+- Fix memory leaks, mostly related to DBus code
+- Compatible with docker 1.10
+- Limit concurrent authentication similar to sshd using 'MaxStartups' setting
+- Fixed up server disconnection UI
+- Navigation fixes 
+
 * Wed Feb 10 2016 Dominik Perpeet <dperpeet@redhat.com> - 0.93-3
 - Fix session path rhbz#1306145