Create symlink during install

This commit is contained in:
Jip-Hop 2023-08-14 15:42:20 +02:00
parent 6c0e790411
commit 5317c3f833
2 changed files with 44 additions and 31 deletions

View File

@ -30,7 +30,7 @@ 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
### 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.
@ -40,38 +40,40 @@ Unfortunately since version 22.12.3 TrueNAS SCALE no longer includes systemd-nsp
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)).
Additionally the install command will create a symlink from `/usr/bin/jlmkr` to `jlmkr.py`. Thanks this this you can now run the `jlmkr` command from anywhere (instead of having to run `./jlmkr.py` from inside the directory where you've placed it).
## Create Jail
Creating a jail is interactive. You'll be presented with questions which guide you through the process.
```shell
./jlmkr.py create myjail
jlmkr create myjail
```
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. 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`.
In order to start a jail automatically after TrueNAS boots, run `jlmkr 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 && jlmkr start myjail`.
## Additional Commands
### Start Jail
```shell
./jlmkr.py start myjail
jlmkr start myjail
```
### List Jails
```shell
./jlmkr.py list
jlmkr list
```
### Remove Jail
```shell
./jlmkr.py remove myjail
jlmkr remove myjail
```
For additional commands we can use `machinectl`, `systemctl` and `journalctl` directly. The `jlmkr.py` script does not play a role here.
@ -110,7 +112,7 @@ systemd-run --machine myjail --quiet --pipe --wait --collect --service-type=exec
## Edit Jail Config
Once you've created a jail, it will exist in a directory inside the `jails` dir next to `jlmkr.py`. For example `./jails/myjail` if you've named your jail `myjail`. You may edit the jail configuration file. You'll have to stop the jail and start it again with `jlmkr.py` for these changes to take effect.
Once you've created a jail, it will exist in a directory inside the `jails` dir next to `jlmkr.py`. For example `/mnt/mypool/jailmaker/jails/myjail` if you've named your jail `myjail`. You may edit the jail configuration file. You'll have to stop the jail and start it again with `jlmkr` for these changes to take effect.
## Networking

View File

@ -35,7 +35,7 @@ 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, thanks to systemd-nspawn!"
VERSION = '0.0.6'
VERSION = '0.0.7'
JAILS_DIR_PATH = 'jails'
JAIL_CONFIG_NAME = 'config'
@ -770,33 +770,44 @@ def list_jails():
print("\nCurrently running:\n")
subprocess.run(['machinectl', 'list'])
def install_jailmaker_dependencies():
def install_jailmaker():
# Check if command exists in path
if shutil.which('systemd-nspawn'):
print("systemd-nspawn is already installed.")
return
else:
print("Installing jailmaker dependencies...")
print("Installing jailmaker dependencies...")
original_permissions = {}
original_permissions = {}
print("Temporarily enable apt and dpkg (if not already enabled) to install systemd-nspawn.")
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)
# 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)
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.")
# Restore original permissions
print("Restore permissions of apt and dpkg.")
for file, original_permission in original_permissions.items():
stat_chmod(file, original_permission)
for file, original_permission in original_permissions.items():
stat_chmod(file, original_permission)
target = '/usr/bin/jlmkr'
print("Done installing jailmaker dependencies.")
# Check if command exists in path
if shutil.which('jlmkr'):
print("The jlmkr command is available.")
elif not os.path.lexists(target):
print(f"Creating symlink {target} to {SCRIPT_PATH}.")
os.symlink(SCRIPT_PATH, target)
else:
print(f"File {target} already exists... Maybe it's a broken symlink from a previous install attempt?")
print(f"Skipped creating new symlink {target} to {SCRIPT_PATH}.")
print("Done installing jailmaker.")
def main():
if os.stat(SCRIPT_PATH).st_uid != 0:
@ -820,7 +831,7 @@ def main():
subparsers.add_parser(name='list', epilog=DISCLAIMER)
subparsers.add_parser(name='install', epilog=DISCLAIMER, help="Install jailmaker dependencies")
subparsers.add_parser(name='install', epilog=DISCLAIMER, help="Install jailmaker dependencies and create symlink")
if os.getuid() != 0:
parser.print_usage()
@ -848,7 +859,7 @@ def main():
list_jails()
elif args.subcommand == 'install':
install_jailmaker_dependencies()
install_jailmaker()
elif args.subcommand:
parser.print_usage()