diff --git a/client.py b/client.py
deleted file mode 100755
index 40d54a3b2f28c81f0e8a73ae32e1a40f375fe882..0000000000000000000000000000000000000000
--- a/client.py
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/usr/bin/python3
-
-from dbus_next.aio import MessageBus, ProxyInterface
-import dbus_next.introspection as intr
-from dbus_next.message import Message
-from dbus_next.service import ServiceInterface, method, dbus_property, signal
-from dbus_next import Variant, DBusError, BusType, MessageType, RequestNameReply
-
-import asyncio
-import os
-from typing import Union, Optional, Callable, Dict, List, Set
-
-
-async def main():
-    bus = await MessageBus(bus_type=BusType.SYSTEM, negotiate_unix_fd=True).connect()
-
-    ins = await bus.introspect('cz.ucw.shipcat', '/cz/ucw/ShipCat')
-
-    pxy = bus.get_proxy_object('cz.ucw.shipcat', '/cz/ucw/ShipCat', ins)
-    pif = pxy.get_interface('cz.ucw.ShipCat')
-
-    # fd = os.open('/dev/null', os.O_RDWR)
-    # xx = await pif.call_shell(0, 1, 2)
-
-    xx = await pif.call_check('test')
-
-    print(xx)
-
-
-asyncio.get_event_loop().run_until_complete(main())
diff --git a/server.py b/server.py
deleted file mode 100755
index 3e066257ee0bc2bf0d0034e85dfa531ea0e7405e..0000000000000000000000000000000000000000
--- a/server.py
+++ /dev/null
@@ -1,257 +0,0 @@
-#!/usr/bin/python3
-
-import asyncio
-from dbus_next import Message, Variant, DBusError, BusType, MessageType, RequestNameReply
-from dbus_next.aio import MessageBus, ProxyInterface
-import dbus_next.introspection as intr
-import logging
-import os
-import sys
-from typing import Union, Optional, Dict, List, Set, Any
-
-from shipcat.config import GlobalConfig, ContainerConfig, ConfigError
-
-
-class BusLogic:
-    config: GlobalConfig
-    bus: MessageBus
-    msg_tasks: Set[asyncio.Task]
-    dbus_iface: ProxyInterface
-    object_tree: Any
-    method_list: List[intr.Method]
-    method_dict: Dict[str, intr.Method]
-    interface_intro: intr.Interface
-
-    def __init__(self, config: GlobalConfig) -> None:
-        self.config = config
-
-        self.logger = logging.getLogger('shipscat')
-        if config.verbosity > 0:
-            self.logger.setLevel(logging.DEBUG)
-        else:
-            self.logger.setLevel(logging.INFO)
-        self.logger.propagate = True
-
-        self.msg_tasks = set()
-
-        self.object_tree = {
-            'cz': {
-                'ucw': {
-                    'ShipCat': True,
-                }
-            }
-        }
-
-        self.method_list = [
-            intr.Method(
-                name='Check',
-                in_args=[
-                    intr.Arg('s', intr.ArgDirection.IN, 'container'),
-                ],
-            ),
-            intr.Method(
-                name='Shell',
-                in_args=[
-                    intr.Arg('h', intr.ArgDirection.IN, 'stdin_fd'),
-                    intr.Arg('h', intr.ArgDirection.IN, 'stdout_fd'),
-                    intr.Arg('h', intr.ArgDirection.IN, 'stderr_fd'),
-                ],
-                out_args=[
-                    intr.Arg('i', intr.ArgDirection.OUT, 'exit_code'),
-                ],
-            ),
-        ]
-
-        self.method_dict = {m.name: m for m in self.method_list}
-
-        self.interface_intro = intr.Interface(
-            name='cz.ucw.ShipCat',
-            methods=self.method_list,
-        )
-
-    async def loop(self) -> None:
-        self.bus = await MessageBus(bus_type=BusType.SYSTEM, negotiate_unix_fd=True).connect()
-
-        # Obtain proxy interface for org.freedesktop.DBus
-        dbus_intro = await self.bus.introspect(bus_name='org.freedesktop.DBus', path='/org/freedesktop/DBus')
-        dbus_proxy = self.bus.get_proxy_object(bus_name='org.freedesktop.DBus', path='/org/freedesktop/DBus', introspection=dbus_intro)
-        self.dbus_iface = dbus_proxy.get_interface('org.freedesktop.DBus')
-
-        self.bus.add_message_handler(self.handle_message)
-
-        rn = await self.bus.request_name('cz.ucw.shipcat')
-        assert rn == RequestNameReply.PRIMARY_OWNER
-
-        await self.bus.wait_for_disconnect()
-
-    def handle_message(self, msg: Message) -> Optional[Union[Message, bool]]:
-        self.logger.debug(f'Got message: type={msg.message_type.name} dest={msg.destination} path={msg.path} iface={msg.interface} member={msg.member} sender={msg.sender} fds={msg.unix_fds}')
-
-        if (msg.destination == 'cz.ucw.shipcat'
-           and msg.interface == 'org.freedesktop.DBus.Introspectable'
-           and msg.member == 'Introspect'):
-            self.close_fds(msg)
-            result = self.handle_introspect(msg)
-
-        elif (msg.destination == 'cz.ucw.shipcat'
-              and msg.interface == 'cz.ucw.ShipCat'
-              and msg.message_type == MessageType.METHOD_CALL
-              and msg.member in self.method_dict
-              and msg.signature == self.method_dict[msg.member].in_signature):
-            result = self.handle_method_call(msg)
-
-        else:
-            self.close_fds(msg)
-            result = None
-
-        return result
-
-    def close_fds(self, msg: Message) -> None:
-        # XXX: The dbus-next library leaks file descriptors. Work around it.
-        # (see https://github.com/altdesktop/python-dbus-next/issues/162)
-        for fd in msg.unix_fds:
-            os.close(fd)
-        msg.unix_fds = []
-
-    def handle_method_call(self, msg: Message) -> bool:
-        async def async_method_call(msg):
-            self.logger.debug(f'Calling method {msg.member}')
-            try:
-                reply = await getattr(self, 'handle_' + msg.member)(msg)
-            except DBusError as e:
-                self.logger.debug(f'DBusError: {e}')
-                reply = Message.new_error(msg, e.type, e.text)
-            except Exception as e:
-                self.logger.error(f'Internal error: {e}')
-                reply = Message.new_error(msg, 'cz.ucw.ShipCat.Error.Internal', 'Internal error')
-            self.bus.send(reply)
-            self.close_fds(msg)
-
-        task = asyncio.create_task(async_method_call(msg))
-        self.msg_tasks.add(task)
-        task.add_done_callback(self.msg_tasks.discard)
-        return True
-
-    def handle_introspect(self, msg: Message) -> Message:
-        self.logger.debug(f'Introspecting {msg.path}')
-        intro = intr.Node.default(msg.path)
-        # We do not want to speak ObjectManager-ish
-        intro.interfaces = [i for i in intro.interfaces if i.name != 'org.freedesktop.DBus.ObjectManager']
-
-        if msg.path == '/':
-            path = [""]
-        else:
-            path = msg.path.split('/')
-        assert path[0] == ""
-
-        i = 1
-        node = self.object_tree
-        while i < len(path) and isinstance(node, dict) and path[i] in node:
-            node = node[path[i]]
-            i += 1
-
-        if i == len(path):
-            if isinstance(node, dict):
-                intro.nodes = [intr.Node(n) for n in sorted(node.keys())]
-            else:
-                intro.interfaces.append(self.interface_intro)
-        return Message.new_method_return(msg, signature='s', body=[intro.tostring()])
-
-    async def handle_Check(self, msg: Message) -> Message:
-        [container] = msg.body
-        await self.setup_container(container, msg)
-
-        ins = await self.bus.introspect('org.freedesktop.systemd1', '/org/freedesktop/systemd1')
-        pxy = self.bus.get_proxy_object('org.freedesktop.systemd1', '/org/freedesktop/systemd1', ins)
-        pif = pxy.get_interface('org.freedesktop.systemd1.Manager')
-        p = await pif.call_get_unit('inetd.service')
-        print(p)
-
-        uns = await self.bus.introspect('org.freedesktop.systemd1', p)
-        uxy = self.bus.get_proxy_object('org.freedesktop.systemd1', p, uns)
-        uif = uxy.get_interface('org.freedesktop.systemd1.Unit')
-        active = await uif.get_active_state()
-        sub_state = await uif.get_sub_state()
-        print(active, sub_state)
-
-        await pif.call_subscribe()
-
-        def cb(a, b, c):
-            self.logger.debug(f'PROP: {a} {b} {c}')
-
-        prif = uxy.get_interface('org.freedesktop.DBus.Properties')
-        prif.on_properties_changed(cb)
-
-        await asyncio.sleep(60)
-
-        await pif.call_unsubscribe()
-
-        return Message.new_method_return(msg)
-
-    async def handle_Shell(self, msg: Message) -> Message:
-        stdin_fd = msg.unix_fds[msg.body[0]]
-        stdout_fd = msg.unix_fds[msg.body[1]]
-        stderr_fd = msg.unix_fds[msg.body[2]]
-
-        cred = await self.dbus_iface.call_get_connection_credentials(msg.sender)
-
-        proc = await asyncio.create_subprocess_exec('/bin/cat', '/etc/profile', stdin=stdin_fd, stdout=stdout_fd, stderr=stderr_fd)
-        await proc.wait()
-
-        return Message.new_method_return(msg, signature='i', body=[proc.returncode])
-
-    async def setup_container(self, name: str, msg: Message) -> ContainerConfig:
-        cred = await self.dbus_iface.call_get_connection_credentials(msg.sender)
-        assert isinstance(cred, dict)
-
-        unix_user_id = cred.get('UnixUserID', None)
-        if isinstance(unix_user_id, Variant) and unix_user_id.signature == 'u':
-            uid = unix_user_id.value
-            assert isinstance(uid, int)
-        else:
-            uid = -1
-
-        unix_group_ids = cred.get('UnixGroupIDs', None)
-        if isinstance(unix_group_ids, Variant) and unix_group_ids.signature == 'a(u)':
-            gids = unix_user_id.value
-        else:
-            gids = []
-
-        try:
-            cc = ContainerConfig.load(self.config, name)
-        except ConfigError as e:
-            self.logger.error(f'{msg.member}({name}) by uid {uid}: {e}')
-            raise DBusError('cz.ucw.ShipCat.Error.ContainerConfig', 'Cannot load container configuration')
-
-        if not self.check_rights(cc, uid, gids):
-            self.logger.error(f'{msg.member}({name}) by uid {uid}: Permission denied')
-            raise DBusError('cz.ucw.ShipCat.Error.PermissionDenied', 'You do not have permission to handle this container')
-
-        self.logger.info(f'{msg.member}({name}) by uid {uid}')
-
-        return cc
-
-    def check_rights(self, cc: ContainerConfig, uid: int, gids: List[int]) -> bool:
-        if uid == 0:
-            return True
-
-        if uid in cc.allowed_users:
-            return True
-
-        for gid in gids:
-            assert isinstance(gid, int)
-            if gid in cc.allowed_groups:
-                return True
-
-        return False
-
-
-try:
-    config = GlobalConfig.load('shipcat.toml')
-except ConfigError as e:
-    print(e, file=sys.stderr)
-    sys.exit(1)
-
-logging.basicConfig(format='%(asctime)-15s %(levelname)-5.5s %(message)s')
-bl = BusLogic(config)
-asyncio.get_event_loop().run_until_complete(bl.loop())