Add exec command

This commit is contained in:
Jip-Hop 2023-08-15 14:45:52 +02:00
parent 35e0d7c2db
commit 1bcd4dbdd4
2 changed files with 32 additions and 10 deletions

View File

@ -68,6 +68,20 @@ jlmkr start myjail
jlmkr list jlmkr list
``` ```
## Execute Command in Jail
You may want to execute a command inside a jail, for example from a shell script or a CRON job. The example below executes the `env` command inside the jail.
```shell
jlmkr exec myjail env
```
This example executes bash inside the jail with a command as additional argument.
```shell
jlmkr exec myjail bash -c 'echo test; echo $RANDOM;'
```
## Edit Jail Config ## Edit Jail Config
```shell ```shell
@ -110,14 +124,6 @@ jlmkr log myjail
Expert users may use the following additional commands to manage jails directly: `machinectl`, `systemd-nspawn`, `systemd-run`, `systemctl` and `journalctl`. The `jlmkr` script uses these commands under the hood and implements a subset of their capabilities. If you use them directly you will bypass any safety checks or configuration done by `jlmkr` and not everything will work in the context of TrueNAS SCALE. Expert users may use the following additional commands to manage jails directly: `machinectl`, `systemd-nspawn`, `systemd-run`, `systemctl` and `journalctl`. The `jlmkr` script uses these commands under the hood and implements a subset of their capabilities. If you use them directly you will bypass any safety checks or configuration done by `jlmkr` and not everything will work in the context of TrueNAS SCALE.
### Run Command in Jail
If you want to run a command inside a jail, for example from a shell script or a CRON job, you may use `systemd-run` with the `--machine` flag. The example below runs the `env` command inside the jail.
```
systemd-run --machine myjail --quiet --pipe --wait --collect --service-type=exec env
```
## Networking ## Networking
By default the jail will have full access to the host network. No further setup is required. You may download and install additional packages inside the jail. Note that some ports are already occupied by TrueNAS SCALE (e.g. 443 for the web interface), so your jail can't listen on these ports. This is inconvenient if you want to host some services (e.g. traefik) inside the jail. To workaround this issue when using host networking, you may disable DHCP and add several static IP addresses (Aliases) through the TrueNAS web interface. If you setup the TrueNAS web interface to only listen on one of these IP addresses, the ports on the remaining IP addresses remain available for the jail to listen on. By default the jail will have full access to the host network. No further setup is required. You may download and install additional packages inside the jail. Note that some ports are already occupied by TrueNAS SCALE (e.g. 443 for the web interface), so your jail can't listen on these ports. This is inconvenient if you want to host some services (e.g. traefik) inside the jail. To workaround this issue when using host networking, you may disable DHCP and add several static IP addresses (Aliases) through the TrueNAS web interface. If you setup the TrueNAS web interface to only listen on one of these IP addresses, the ports on the remaining IP addresses remain available for the jail to listen on.

View File

@ -172,9 +172,17 @@ def passthrough_nvidia(gpu_passthrough_nvidia, systemd_nspawn_additional_args, j
systemd_nspawn_additional_args += nvidia_mounts systemd_nspawn_additional_args += nvidia_mounts
def exec_jail(jail_name, cmd, args):
"""
Execute a command in the jail with given name.
"""
subprocess.run(['systemd-run', '--machine', jail_name, '--quiet', '--pipe',
'--wait', '--collect', '--service-type=exec', cmd] + args, check=True)
def status_jail(jail_name): def status_jail(jail_name):
""" """
Show the status of the systemd service wrapping the jail. Show the status of the systemd service wrapping the jail with given name.
""" """
# Alternatively `machinectl status jail_name` could be used # Alternatively `machinectl status jail_name` could be used
subprocess.run(["systemctl", "status", f"{SYMLINK_NAME}-{jail_name}"]) subprocess.run(["systemctl", "status", f"{SYMLINK_NAME}-{jail_name}"])
@ -987,6 +995,11 @@ def main():
help='open shell in running jail').add_argument( help='open shell in running jail').add_argument(
'name', help='name of the jail') 'name', help='name of the jail')
exec_parser = subparsers.add_parser(name='exec', epilog=DISCLAIMER,
help='execute a command in the jail')
exec_parser.add_argument('name', help='name of the jail')
exec_parser.add_argument('cmd', help='command to execute')
subparsers.add_parser(name='status', epilog=DISCLAIMER, subparsers.add_parser(name='status', epilog=DISCLAIMER,
help='show jail status').add_argument( help='show jail status').add_argument(
'name', help='name of the jail') 'name', help='name of the jail')
@ -1023,7 +1036,7 @@ def main():
# Work relative to this script # Work relative to this script
os.chdir(SCRIPT_DIR_PATH) os.chdir(SCRIPT_DIR_PATH)
args = parser.parse_args() args, additional_args = parser.parse_known_args()
if args.subcommand == 'start': if args.subcommand == 'start':
start_jail(args.name) start_jail(args.name)
@ -1031,6 +1044,9 @@ def main():
elif args.subcommand == 'shell': elif args.subcommand == 'shell':
shell_jail(args.name) shell_jail(args.name)
elif args.subcommand == 'exec':
exec_jail(args.name, args.cmd, additional_args)
elif args.subcommand == 'status': elif args.subcommand == 'status':
status_jail(args.name) status_jail(args.name)