diff --git a/shipcat-wrapper.c b/shipcat-wrapper.c
index 66864bafedd196d4be74501c6a6e984adedd7aa8..8083a6400058036c73c2a7d999c8be10d501b249 100644
--- a/shipcat-wrapper.c
+++ b/shipcat-wrapper.c
@@ -22,6 +22,7 @@
 
 #define NONRET __attribute__((noreturn))
 #define UNUSED __attribute__((unused))
+#define ARRAY_SIZE(a) (int)(sizeof(a) / sizeof(*(a)))
 
 static void NONRET die(const char *fmt, ...)
 {
@@ -93,6 +94,8 @@ static void get_credentials(void)
       if (glen >= (int) sizeof(as_groups))
 	die("Group list too long");
     }
+
+  free(groups);
 }
 
 static void switch_ugid(void)
@@ -104,21 +107,10 @@ static void switch_ugid(void)
     die("Failed to set user id: %m");
 }
 
-int main(int argc UNUSED, char **argv UNUSED)
+static char **make_args(int argc, char **argv)
 {
-  sanitize_fds();
-  umask(0077);
-
-  if (geteuid())
-    die("Must be run setuid");
-
-  get_credentials();
-  switch_ugid();
-
-  char *program = DESTDIR "/usr/bin/shipcat";
-
   char **args = xmalloc(sizeof(char *) * (5 + argc));
-  args[0] = program;
+  args[0] = DESTDIR "/usr/bin/shipcat";
   args[1] = "--as-user";
   args[2] = as_user;
   args[3] = "--as-groups";
@@ -126,14 +118,60 @@ int main(int argc UNUSED, char **argv UNUSED)
   for (int i=1; i<argc; i++)
     args[4+i] = argv[i];
   args[4+argc] = NULL;
+  return args;
+}
 
-  char * const env[] = {
-      "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
-      NULL
+static char **make_env(void)
+{
+  static char *set_env[] = {
+    "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
+  };
+
+  static char *inherit_env[] = {
+    "TERM=",
   };
 
-  if (execve(program, args, env) < 0)
-    die("Cannot execute %s: %m", program);
+  char **env = xmalloc(sizeof(char *) * (ARRAY_SIZE(set_env) + ARRAY_SIZE(inherit_env) + 1));
+  char **ep = env;
+
+  for (int i=0; i < ARRAY_SIZE(set_env); i++)
+    *ep++ = set_env[i];
+
+  for (int i=0; environ[i]; i++)
+    {
+      char *e = environ[i];
+      int elen = strlen(e);
+      for (int j=0; j < ARRAY_SIZE(inherit_env); j++)
+	{
+	  char *p = inherit_env[j];
+	  int plen = strlen(p);
+	  if (elen >= plen && !memcmp(e, p, plen))
+	    {
+	      *ep++ = e;
+	      break;
+	    }
+	}
+    }
+
+  *ep = NULL;
+  return env;
+}
+
+int main(int argc, char **argv)
+{
+  sanitize_fds();
+  umask(0077);
+
+  if (geteuid())
+    die("Must be run setuid");
+
+  get_credentials();
+  switch_ugid();
+
+  char **args = make_args(argc, argv);
+  char **env = make_env();
+  if (execve(args[0], args, env) < 0)
+    die("Cannot execute %s: %m", args[0]);
 
   die("This must never happen");
 }
diff --git a/shipcat.py b/shipcat.py
index 42baeb6fe1d80978b61bd2c973c4a15b9c13a684..d9122cba2ba7b107ac4856156f7c368b6dbad19b 100755
--- a/shipcat.py
+++ b/shipcat.py
@@ -15,6 +15,7 @@ sys.path.append('/tmp/shc/usr/lib/python')
 
 from shipcat.config import GlobalConfig, ContainerConfig, ConfigError
 
+
 def die(msg: str) -> NoReturn:
     print(msg, file=sys.stderr)
     sys.exit(1)
@@ -24,6 +25,21 @@ def progress(msg: str) -> None:
     print(msg, file=sys.stderr, end="", flush=True)
 
 
+def run_command(args: List[str], *rest, **kwargs) -> None:
+    res = subprocess.run(args, *rest, **kwargs)
+    if res.returncode != 0:
+        die('Command failed: ' + " ".join(args))
+
+
+def load_config() -> GlobalConfig:
+    try:
+        # FIXME: Path to config
+        return GlobalConfig.load('shipcat.toml')
+    except ConfigError as e:
+        print(e, file=sys.stderr)
+        sys.exit(1)
+
+
 def setup_container(args: argparse.Namespace, require_root: bool) -> ContainerConfig:
     if os.geteuid() != 0:
         die('This program must be run setuid root')
@@ -104,7 +120,7 @@ class SubIds:
         return SubIdRange(i, size, user)
 
 
-def do_init(args: argparse.Namespace) -> None:
+def cmd_init(args: argparse.Namespace) -> None:
     name = args.name
     cc = setup_container(args, True)
 
@@ -114,9 +130,8 @@ def do_init(args: argparse.Namespace) -> None:
         progress('already exists\n')
     except KeyError:
         progress('creating\n')
-        subprocess.run(
+        run_command(
             ['adduser', '--system', '--group', '--gecos', f'Container {name}', '--disabled-password', cc.user_name],
-            check=True,
         )
         pwd = getpwnam(cc.user_name)
     uid = pwd.pw_uid
@@ -129,9 +144,8 @@ def do_init(args: argparse.Namespace) -> None:
     else:
         progress('allocating\n')
         sur = subuids.alloc_range(cc.user_name, 65536)
-        subprocess.run(
+        run_command(
             ['usermod', '--add-subuids', f'{sur.first}-{sur.first + sur.count - 1}', cc.user_name],
-            check=True,
         )
 
     progress('Subgid range: ')
@@ -142,9 +156,8 @@ def do_init(args: argparse.Namespace) -> None:
     else:
         progress('allocating\n')
         sgr = subgids.alloc_range(cc.user_name, 65536)
-        subprocess.run(
+        run_command(
             ['usermod', '--add-subgids', f'{sgr.first}-{sgr.first + sgr.count - 1}', cc.user_name],
-            check=True,
         )
 
     progress(f'Using user {cc.user_name}, uid {uid}, subuids {sur.first}+{sur.count}, subgids {sgr.first}+{sgr.count}\n')
@@ -175,26 +188,30 @@ def do_init(args: argparse.Namespace) -> None:
     progress(f'{ip}\n')
 
 
-def do_create(args: argparse.Namespace) -> None:
+def service_action(cc: ContainerConfig, action: str) -> None:
+    run_command(
+        ['systemctl', action, f'shc@{cc.container}.service'],
+    )
+
+
+def cmd_create(args: argparse.Namespace) -> None:
     name = args.name
     cc = setup_container(args, False)
 
     data_dir = Path(cc.root_dir) / 'data'
     ip = socket.gethostbyname(name)
 
-    subprocess.run(
+    run_command(
         ['podman', 'pull', cc.image],
-        check=True,
     )
 
-    # FIXME: If the container was running, stop it
+    service_action(cc, 'stop')
 
-    subprocess.run(
+    run_command(
         ['podman', 'rm', '-if', name],
-        check=True,
     )
 
-    subprocess.run(
+    run_command(
         [
             'podman', 'create',
             '--name', name,
@@ -208,12 +225,22 @@ def do_create(args: argparse.Namespace) -> None:
             '--subgidname', cc.user_name,
             cc.image,
         ],
-        check=True,
     )
 
 
-def do_start(args: argparse.Namespace) -> None:
-    pass
+def cmd_start(args: argparse.Namespace) -> None:
+    cc = setup_container(args, False)
+    service_action(cc, 'start')
+
+
+def cmd_stop(args: argparse.Namespace) -> None:
+    cc = setup_container(args, False)
+    service_action(cc, 'stop')
+
+
+def cmd_status(args: argparse.Namespace) -> None:
+    cc = setup_container(args, False)
+    service_action(cc, 'status')
 
 
 def parse_int_list(s: str) -> List[int]:
@@ -236,17 +263,21 @@ create_parser.add_argument('name', help='name of the container')
 start_parser = subparsers.add_parser('start', help='start a container', description='Start a container')
 start_parser.add_argument('name', help='name of the container')
 
+status_parser = subparsers.add_parser('status', help='show container status', description='Show container status')
+status_parser.add_argument('name', help='name of the container')
+
+stop_parser = subparsers.add_parser('stop', help='stop a container', description='Stop a container')
+stop_parser.add_argument('name', help='name of the container')
+
 args = parser.parse_args()
 
-try:
-    config = GlobalConfig.load('shipcat.toml')
-except ConfigError as e:
-    print(e, file=sys.stderr)
-    sys.exit(1)
+actions = {
+    'create': cmd_create,
+    'init': cmd_init,
+    'start': cmd_start,
+    'status': cmd_status,
+    'stop': cmd_stop,
+}
 
-if args.action == 'init':
-    do_init(args)
-elif args.action == 'create':
-    do_create(args)
-elif args.action == 'start':
-    do_start(args)
+config = load_config()
+actions[args.action](args)