# SPDX-License-Identifier: GPL-2.0-only [suite micoforia] caption = Subcommands mansect = 8 manual_title = System Manager's Manual [supercommand micoforia] [description] DESCRIPTION1() DESCRIPTION2() DESCRIPTION3() In addition to global options which apply to all subcommands, each subcommand has its own set of options. The usual "--" separator must be used to separate global options from subcommand specific options. [/description] synopsis = [global-options...] [--] [ [subcommand-options...]] purpose = SLOGAN() [option general-options-section] summary = General options flag ignored [option help] summary = print help and exit short_opt = h [option detailed-help] summary = print help, including all details, and exit [option version] summary = print version and exit short_opt = V [option config-file] short_opt = c summary = use alternative config file (default: ~/.micoforiarc) typestr = path arg_info = required_arg arg_type = string [help] Options may be given at the command line or in the configuration file. As usual, if an option is given both at the command line and in the configuration file, the command line option takes precedence. The config file may contain global options as well as options for any subcommand, but subcommand specific options must be placed in a separate section. See the Examples section of the man page. [/help] [option loglevel] summary = control amount of logging short_opt = l arg_info = required_arg arg_type = string typestr = severity values = { LSGLL_DEBUG = "debug", LSGLL_INFO = "info", LSGLL_NOTICE = "notice", LSGLL_WARNING = "warning", LSGLL_ERROR = "error", LSGLL_CRIT = "crit", LSGLL_EMERG = "emerg" } default_val = warning [help] Log only messages with severity greater or equal than the given value. Possible values: debug: produces really noisy output. info: still noisy, but won't fill up the disk quickly. notice: indicates normal, but significant event. warning: unexpected events that can be handled. error: unhandled error condition. crit: system might be unreliable. emerg: last message before exit. [/help] [option general-options-section] summary = Global Container Options flag ignored [help] The options in this section apply to all containers. Most of them have a per-container counterpart which can be specified to override the global default. [/help] [option default-root-prefix] summary = path to the parent directory of the container root file systems typestr = directory arg_info = required_arg arg_type = string default_val = /var/lib/micoforia [help] For containers which do not specify their own root directory the path to the container root is derived from the argument of this option by appending a slash and the container name. [/help] [option logdir] summary = directory which contains the container log files arg_info = required_arg arg_type = string typestr = directory default_val = /var/log/micoforia [help] The log messages of each container are written to a dedicated logfile. This option controls in which directroy these files are written (start subcommand) or expected (log subcommand). Nothing is written to the logfile if the container is started in foreground mode. [/help] [option default-pre-start-hook] summary = command to be executed before the container starts typestr = command arg_info = required_arg arg_type = string default_val = true [help] This hook is run early during container startup. All veth device pairs have been created, but no namespace or cgroup operations have been performed at this point. If the root file system of the container must be prepared, this is the right place to perform this task. Unlike the pre exec hook described below, this hook is only called once. The following environment variables are set: MICOFORIA_CONTAINER_NAME, MICOFORIA_IFSPECS, MICOFORIA_ROOT_DIR. [/help] [option default-pre-exec-hook] summary = command to be executed before /sbin/init is executed typestr = command arg_info = required_arg arg_type = string default_val = true [help] This runs with all namespaces already unshared and cgroup settings applied but before the root directory is switched to the container root. The hostname has already been changed to the container name and the network interfaces have been renamed to eth0, eth1, etc. This is the right place to perform additional cgroup or namespace operations. When the container is rebooted, the pre-exec is called again, just before control is handed over to the new init process. Only MICOFORIA_ROOT_DIR is set in this hook. [/help] [option default-init] summary = control the handover to the init process of the container typestr = command arg_info = required_arg arg_type = string default_val = /sbin/init [help] This program is executed as the last step of the container startup procedure as pid 1. At this point the root directory of the process has already been changed, so the given argument refers to a path relative to the container root directory. [/help] [option default-bridge] summary = ethernet bridge to use by default typestr = bridge flag multiple arg_info = required_arg arg_type = string default_val = micoforia [help] Applies to all containers which do not specify their own network interface(s) with --net. If this is given multiple times, containers will be equipped with multiple interfaces. [/help] [option default-cgroup-dac] summary = specify which device nodes containers may access/create by default typestr = dacspec flag multiple arg_info = required_arg arg_type = string [help] Applies to all containers which do not specify their own access control lists. May be given multiple times. Each device access control specifier must be of the form {allow|deny} , where is a suitable device access control string for the devices.allow or devices.deny file of the cgroup-v1 controller. Order matters. If this option is not given, and the corresponding per-container option is not given either, a reasonable default applies which allows access to the most common character devices (/dev/zero, /dev/null, /dev/urandom, etc.) but denies access to most other devices including all block devices. Example: allow c 1:5 rwm [/help] [option default-cpu-cores] summary = Number of cores to use by default (zero means unlimited) typestr = num arg_info = required_arg arg_type = uint32 default_val = 0 [help] The limit is enforced by the cpu cgroup-v2 controller. Note that in contrast to the cpuset controller of cgroup-v1 this controller does not restrict the container to a set of admissible CPUs. Instead, it limits the number of CPU cycles per time unit for the processes in the cgroup. [/help] [option default-memory-limit] summary = Memory usage throttle limit (zero means no limit) typestr = gigabytes arg_info = required_arg arg_type = uint32 default_val = 0 [help] The value specified here is written to the cgroup-v2 memory.high control file of all containers which do not specify their own limit. [/help] [option default-io-max] summary = I/O limit (zero means no limit) flag multiple typestr = iospec arg_info = required_arg arg_type = string [help] The I/O specifier argument must be a valid string for the io.max file of the cgroup-v2 controller. For example, the string "1:5 rbps=1024" limits the read I/O rate for the /dev/zero device to 1K per second. [/help] [option default-capdrop] summary = Capabilities to drop by default typestr = capspec flag multiple arg_info = required_arg arg_type = string [help] The capability specifier argument is the text representation of a capability, like CAP_SYS_MODULE. All given capabilities will be dropped from the bounding set of the container init process, hence from all all processes of the container. If this option is not given, and no per-container capabilities to drop are given either, CAP_SYS_MODULE, CAP_SYS_TIME, and CAP_SYS_RESOURCE are dropped. See capabilities(7) for the list of capabilities and their meaning. [/help] [option default-tty] summary = Minor number of a tty device to capture by default typestr = minor flag multiple arg_info = required_arg arg_type = uint32 [help] Normally the container's init process starts at least one "getty" login session on a tty port /dev/ttyX, where X is the minor device ID. This option lets you capture these login sessions and forward them to another micoforia process executing the "attach" subcommand. For each time the option is given, the device with the given minor device number is captured. If this is not given, /dev/tty1 will be captured. [/help] [option general-options-section] summary = Per-Container Options flag ignored [help] These override the global container options above. Most of them take a compound argument of the form , where the first part is the name of the container to which the option should be applied. Unless noted otherwise, if both a global option and the corresponding per-container option is given, the per-container option takes precedence. [/help] [option container] summary = name of the container flag multiple typestr = name arg_info = required_arg arg_type = string [help] Used for the hostname, the name of the veth interfaces and the name of the cgroup directory. The name may only contain characters of the set [a-zA-Z0-9-] and the length must not exceed 32 characters. This does not need to be given if one of the compound options below are given instead. [/help] [option pre-start-hook] summary = See --default-pre-start-hook flag multiple typestr = name:command arg_info = required_arg arg_type = string [option pre-exec-hook] summary = See --default-pre-exec-hook flag multiple typestr = name:command arg_info = required_arg arg_type = string [option init] summary = See --default-init typestr = name:command flag multiple arg_info = required_arg arg_type = string [option net] summary = Equip the container with a non-default network interface flag multiple typestr = name:ifspec arg_info = required_arg arg_type = string [help] The interface specifier is of the form bridge[:hwaddr]. If no hardware address is given, a random address will be used. See --default-bridge. Unlike the other compound options of this section, this option is cumulative in that multiple options with the same container name do not override each other but accumulate, resulting in a container with multiple network interfaces. [/help] [option root-directory] summary = Path to the container root directory. See --default-root-prefix. flag multiple typestr = name:path arg_info = required_arg arg_type = string [help] [/help] [option cgroup-dac] summary = See --default-cgroup-dac typestr = name:dacspec flag multiple arg_info = required_arg arg_type = string [option cpu-cores] summary = See --default-cpu-cores typestr = name:num flag multiple arg_info = required_arg arg_type = string [option memory-limit] summary = See --default-memory-limit typestr = name:gigabytes flag multiple arg_info = required_arg arg_type = string [option io-max] summary = See --default-io-max flag multiple typestr = name:iospec arg_info = required_arg arg_type = string [option capdrop] summary = See --default-capdrop flag multiple typestr = name:capspec arg_info = required_arg arg_type = string [option tty] summary = See --default-tty typestr = name:minor flag multiple arg_info = required_arg arg_type = string [introduction] micoforia supports the subcommands described below. If no subcommand is given, the list of available subcommands is shown and the program terminates successfully without performing any further action. [/introduction] [subcommand start] purpose = start one or more containers non-opts-name = [...] [description] If no container is given, all configured containers are started. [/description] [option foreground] short_opt = F summary = do not run as background daemon [help] Normally, the process detaches from the console and continues to run in the background. When this option is given, only a single container can be started, and this container will run with its /dev/console device redirected to the local tty, making the container startup messages visible on the local tty. Moreover, stdin is forwarded to the first configured tty device (/dev/tty1 by default) of the container, and anything received from the other end of the forwarding is dumped to stdout. This allows for logins on the "local" console of the container, provided the container starts getty process which listens on the tty device. [/help] [subcommand stop] purpose = shutdown one or more containers non-opts-name = [...] [description] This subcommand works by executing halt(8) in container context. If no container is given, halt(8) is executed in all configured container contexts. [/description] [option wait] short_opt = w summary = wait until all containers have terminated [help] Without --wait the micoforia process which executes the stop subcommand exits after spawning one halt(8) process per container to be stopped. If --wait is given, the subcommand waits until all containers have terminated or the timeout expires. This is handy for system shutdown scripts which are supposed to terminate all running containers. [/help] [closing] If --wait is not given, the subcommand exits successfully if and only if all signals were sent successfully. With --wait the subcommand exits successfully if, additionally, all signalled processes have terminated before the timeout expires. [/closing] [subcommand reboot] purpose = reboot containers non-opts-name = [...] [description] Containers are rebooted and killed by sending a signal to a micoforia process which executes the start subcommand. [/description] [subcommand kill] purpose = force containers to terminate non-opts-name = [...] [description] This works like the reboot subcommand, but a different signal is used to notify the container. [/description] [option wait] short_opt = w summary = wait until all signalled containers have terminated [help] Without --wait the micoforia process which executes the kill subcommand exits right after the underlying kill(2) system call returns. At this point the signalled process might still be alive although SIGKILL was sent. If --wait is given, the process waits until the signalled processes have terminated or the timeout expires. [/help] [subcommand ls] purpose = list containers non-opts-name = [...] [description] Several listing modes are available. By default, only the running containers are listed. If no container name is given, all configured containers are taken into account. [/description] [option all] short_opt = a summary = Also list containers which are not running [option quiet] short_opt = q summary = Do not print any output [help] For scripts to determine from the exit code whether all of the given containers are running. [/help] [option long] short_opt = l summary = Show also the pid, and the cpu and memory limits [help] This overrides --quiet. That is, if both --quiet and --long are given, the long listing is shown, [/help] [option verbose] short_opt = v summary = Show all container settings, one setting per line [help] This overrides --quiet and --long. [/help] [closing] The subcommand exits successfully if and only if all given/configured containers could be listed. Unless --all is given, it is considered an error if a given container is not running. In particular, when ls is executed with no arguments at all, it exits successfully if and only if all configured containers are running. [/closing] [subcommand ps] purpose = print process list of one or more containers non-opts-name = [...] [description] This runs pstree(1). The container init process is always the third process shown. Process IDs refer to the parent PID namespace, which is why the process ID of the container init is not shown as 1. [/description] [option all] short_opt = a summary = also show the two micoforia processes [subcommand attach] purpose = map the console of a running container to the local terminal. non-opts-name = [...] [description] It is an error if stdin is not associated with a terminal device. [/description] [option tty] short_opt = t summary = terminal to connect arg_info = required_arg arg_type = uint32 typestr = minor default_val = 1 [help] This operation can only succeed if the given tty is forwarded by the container. See --tty and --default-tty. [/help] [option force] short_opt = f summary = don't fail but steal the tty if it is already attached [subcommand help] purpose = list available subcommands or print subcommand-specific help non-opts-name = [subcommand] [description] Without any arguments, help prints the list of available subcommands. When called with a subcommand name argument, it prints the help text of the given subcommand. [/description] [option long] short_opt = l summary = show the long help text [help] If the optional argument is supplied, the long help text contains the synopsis, the purpose and the description of the specified subcommand, followed by the option list including summary and help text of each option. Without --long, the short help is shown instead. This omits the description of the subcommand and the option help. If no subcommand is supplied but --long is given, the list contains the purpose of each subcommand. [/help] [subcommand configtest] purpose = run a configuration file syntax test [description] This subcommand checks the command line options and the configuration file for syntactic and semantic correctness. It either reports "Syntax Ok" and exits successfully or prints information about the first error and terminates with exit code 1. [/description] [subcommand edit] purpose = edit the configuration file [description] The editor to start is derived from the EDITOR environment variable. If this variable is not set, vi is assumed. [/description] [subcommand enter] purpose = run a command in a container namespace non-opts-name = [ [arg...]] [description] This executes the nsenter(1) command to enter the namespaces of the init process of the given container. If no command is given, the login command is run to start a root shell. [/description] [subcommand log] purpose = show the log file for the given container non-opts-name = [] [description] This executes cat(1) or less(1), depending on whether or not stdin and stdout are associated with a terminal device. [/description] [section Notes] .SS The Cgroup File Systems There are two implementations of Linux control groups called .I cgroup-v1 and .IR cgroup-v2 . Both come with their own pseudo filesystem. .B micoforia requires both file systems to be mounted at .IR /var/cgroup and .IR /var/cgroup2 . Version 1 cgroups are only used to enforce device access control for the containers, so the cgroup-v1 pseudo filesystem should be mounted with only this controller enabled. See the Examples section below for how to do this. Future versions of .B micoforia might switch to the devices controller of cgroup-v2. .SS Container Names The container name is used also for the name of the network device and as a directory name if no explicit root directory is given with --root-prefix. Therefore container names must not exceed 32 characters, which must all be alphanumeric or '-'. In particular, whitespace and underscore ('_') are not permitted. [/section] [section Examples] .IP \(bu 2 Create a bash alias named .I m7a for .I micoforia which activates debug messages and already includes the double dash to separate global options from subcommand options: .RS 6 .EX .B alias m7a='micoforia --loglevel debug --' .EE .RE .IP \(bu 2 Set up an ethernet bridge named .IR micoforia , add the physical interface .I eth1 to it and give the bridge interface an IP address: .RS 6 .EX .B brctl addbr micoforia .B ip link set up micoforia .B brctl addif micoforia eth1 .B ip a a 192.168.137.1/24 dev micoforia .EE .RE .IP \(bu 2 Mount the two cgroup file systems, but only activate the .I devices controller of cgroup-v1: .RS 6 .EX .B mkdir -p /var/cgroup && mount -t cgroup -o devices cgroup /var/cgroup .B mkdir -p /var/cgroup2 && mount -t cgroup2 cgroup2 /var/cgroup2 .EE .RE .IP \(bu 2 Entries for .I /etc/fstab to mount the cgroup file systems automatically at boot: .RS 6 .EX .B none /var/cgroup cgroup devices 0 0 .B none /var/cgroup2 cgroup2 defaults 0 0 .EE .RE .IP \(bu 2 Download a Debian10 root file system to .IR /var/lib/micoforia/debian10 , set the root password and let micoforia set the hostname .RS 6 .EX .B debootstrap --variant=minbase buster /var/lib/micoforia/debian10 http://deb.debian.org/debian/ .B chroot /var/lib/micoforia/debian10 passwd .B rm -f /var/lib/micoforia/debian10/etc/hostname .EE .RE .IP \(bu 2 Download a minimal Ubuntu-18.04 root file system to .IR /var/lib/micoforia/c1 , set the root password and configure the .I eth0 interface, using a static IP address: .RS 6 .EX .B debootstrap --include openssh-server --include ifupdown bionic /var/lib/micoforia/c1 http://de.archive.ubuntu.com/ubuntu .B chroot /var/lib/micoforia/c1 passwd .B printf 'auto eth0\(rsniface eth0 inet static\(rsnaddress 192.168.137.2/24\(rsn' \ >> /var/lib/micoforia/c1/etc/network/interfaces .B echo 'PermitRootLogin yes' >> /var/lib/micoforia/c1/etc/ssh/sshd_config .EE .RE .IP \(bu 2 Start the container in foreground mode: .RS 6 .EX .B micoforia --container c1 --start --foreground .EE .RE .IP \(bu 2 Attach to .I tty1 of the running container: .RS 6 .EX .B m7a attach c1 .EE .RE .IP \(bu 2 Ask the container to shut down, and wait for the shutdown procedure to complete: .RS 6 .EX .B m7a stop --wait c1 .EE .RE .IP \(bu 2 Check whether the container is running: .RS 6 .EX .B m7a ls --quiet c1 && echo yes || echo no .EE .RE .IP \(bu 2 A simple config file: .RS 6 .EX .B # two global options .B loglevel info .B container c1 .B # an option for the "attach" subcommand .B [start] .B \ \ \ \ tty 2 .EE .RE [/section] [section copyright] Written by AUTHOR() .br Copyright (C) COPYRIGHT_YEAR() AUTHOR() .br License: LICENSE() .br This is free software: you are free to change and redistribute it. .br There is NO WARRANTY, to the extent permitted by law. .P Web page: .UR URL() .UE .br Git clone `URL': .UR CLONE_URL() .UE .br Gitweb: .UR GITWEB_URL() .UE .br Author's home page: .UR HOME_URL() .UE .br Report bugs to .MT EMAIL() AUTHOR() .ME [/section] [section see also] .BR lxc (7), .BR brct l(8), .BR ip (8) .BR pstree (1) [/section]