Add install command

This commit is contained in:
Jip-Hop 2023-08-12 18:14:09 +02:00
parent cd0179cd83
commit 71836a11cb
2 changed files with 46 additions and 5 deletions

View File

@ -34,6 +34,16 @@ chmod +x jlmkr.py
The `jlmkr.py` script (and the jails + config it creates) are now stored on the `jailmaker` dataset and will survive updates of TrueNAS SCALE.
## Install Jailmaker Dependencies
Unfortunately since version 22.12.3 TrueNAS SCALE no longer includes systemd-nspawn. In order to use jailmaker, we need to first install systemd-nspawn using the command below.
```shell
./jlmkr.py install
```
We need to do this again after each update of TrueNAS SCALE. So it is recommended to schedule this command as Post Init Script (see [Autostart Jail on Boot](#autostart-jail-on-boot)).
## Create Jail
Creating a jail is interactive. You'll be presented with questions which guide you through the process.
@ -46,7 +56,7 @@ After answering a few questions you should have your first jail up and running!
### Autostart Jail on Boot
In order to start a jail automatically after TrueNAS boots, run `/mnt/mypool/jailmaker/jlmkr.py start myjail` as Post Init Script with Type `Command` from the TrueNAS web interface.
In order to start a jail automatically after TrueNAS boots, run `/mnt/mypool/jailmaker/jlmkr.py start myjail` as Post Init Script with Type `Command` from the TrueNAS web interface. If you want to automatically install systemd-nspawn if it's not already installed (recommended to keep working after a TrueNAS SCALE update) then you may use a command such as this instead: `/mnt/mypool/jailmaker/jlmkr.py install && /mnt/mypool/jailmaker/jlmkr.py start myjail`.
## Additional Commands
@ -128,8 +138,6 @@ To make passthrough of the nvidia GPU work, you need to schedule a Pre Init comm
TODO: write comparison between systemd-nspawn (without jailmaker), LXC, VMs, Docker (on the host).
## Known Issues
### Incompatible Distros
The rootfs image `jlmkr.py` downloads comes from the [Linux Containers Image server](https://images.linuxcontainers.org). These images are made for LXC. We can use them with systemd-nspawn too, although not all of them work properly. For example, the `alpine` image doesn't work well. If you stick with common systemd based distros (Debian, Ubuntu, Arch Linux...) you should be fine.

View File

@ -4,6 +4,7 @@ import argparse
import configparser
import contextlib
import ctypes
import glob
import hashlib
import os
import re
@ -32,9 +33,9 @@ DISCLAIMER = f"""{YELLOW}{BOLD}USE THIS SCRIPT AT YOUR OWN RISK!
IT COMES WITHOUT WARRANTY AND IS NOT SUPPORTED BY IXSYSTEMS.{NORMAL}"""
DESCRIPTION = "Create persistent Linux 'jails' on TrueNAS SCALE, with full access to all files \
via bind mounts, without modifying the host OS thanks to systemd-nspawn!"
via bind mounts, thanks to systemd-nspawn!"
VERSION = '0.0.4'
VERSION = '0.0.5'
JAILS_DIR_PATH = 'jails'
JAIL_CONFIG_NAME = 'config'
@ -768,6 +769,33 @@ def list_jails():
print("\nCurrently running:\n")
subprocess.run(['machinectl', 'list'])
def install_jailmaker_dependencies():
# Check if command exists in path
if shutil.which('systemd-nspawn'):
print("systemd-nspawn is already installed.")
return
print("Installing jailmaker dependencies...")
original_permissions = {}
print("Temporarily enable apt and dpkg (if not already enabled) to install systemd-nspawn.")
# Make /bin/apt* and /bin/dpkg* files executable
for file in (glob.glob('/bin/apt*') + (glob.glob('/bin/dpkg*'))):
original_permissions[file] = os.stat(file).st_mode
stat_chmod(file, 0o755)
subprocess.run(['apt-get', 'update'], check=True)
subprocess.run(['apt-get', 'install', '-y', 'systemd-container'], check=True)
# Restore original permissions
print("Restore permissions of apt and dpkg.")
for file, original_permission in original_permissions.items():
stat_chmod(file, original_permission)
print("Done installing jailmaker dependencies.")
def main():
if os.stat(__file__).st_uid != 0:
@ -791,6 +819,8 @@ def main():
subparsers.add_parser(name='list', epilog=DISCLAIMER)
subparsers.add_parser(name='install', epilog=DISCLAIMER, help="Install jailmaker dependencies")
if os.getuid() != 0:
parser.print_usage()
fail("Run this script as root...")
@ -816,6 +846,9 @@ def main():
elif args.subcommand == 'list':
list_jails()
elif args.subcommand == 'install':
install_jailmaker_dependencies()
elif args.subcommand:
parser.print_usage()