Provided by: mmdebstrap_1.4.3-6_all bug

NAME

       mmdebstrap - multi-mirror Debian chroot creation

SYNOPSIS

       mmdebstrap [OPTION...] [SUITE [TARGET [MIRROR...]]]

DESCRIPTION

       mmdebstrap creates a Debian chroot of SUITE into TARGET from one or more MIRRORs. It is meant as an
       alternative to the debootstrap tool (see section DEBOOTSTRAP). In contrast to debootstrap it uses apt to
       resolve dependencies and is thus able to use more than one mirror and resolve more complex dependency
       relationships. See section OPERATION for an overview of how mmdebstrap works internally.

       The SUITE option may either be a valid release code name (eg, sid, bookworm, trixie) or a symbolic name
       (eg, unstable, testing, stable, oldstable). Any suite name that works with apt on the given mirror will
       work. The SUITE option is optional if no TARGET and no MIRROR option is provided.  If SUITE is missing,
       then the information of the desired suite has to come from standard input as part of a valid apt
       sources.list file or be set up via hooks.  The value of the SUITE argument will be used to determine
       which apt index to use for finding out the set of "Essential:yes" packages and/or the set of packages
       with the right priority for the selected variant. This functionality can be disabled by choosing the
       empty string for SUITE. See the section VARIANTS for more information.

       The TARGET option may either be the path to a directory, the path to a tarball filename, the path to a
       squashfs image, the path to an ext2 image, a FIFO, a character special device, or "-".  The TARGET option
       is optional if no MIRROR option is provided. If TARGET is missing or if TARGET is "-", an uncompressed
       tarball will be sent to standard output. Without the --format option, TARGET will be used to choose the
       format. See the section FORMATS for more information.

       The MIRROR option may either be provided as a URI, in apt one-line format, as a path to a file in apt's
       one-line or deb822-format, or "-".  If no MIRROR option is provided, then <http://deb.debian.org/debian>
       is used as the default. If SUITE does not refer to "unstable" or "testing", then SUITE-updates and
       SUITE-security mirrors are automatically added. If a MIRROR option starts with "deb " or "deb-src " then
       it is used as a one-line format entry for apt's sources.list inside the chroot. If a MIRROR option
       contains a "://" then it is interpreted as a mirror URI and the apt line inside the chroot is assembled
       as "deb [arch=A] B C D" where A is the host's native architecture, B is the MIRROR, C is the given SUITE
       and D is the components given via --components (defaults to "main"). If a MIRROR option happens to be an
       existing file, then its contents are written into the chroot's sources.list (if the first MIRROR is a
       file in one-line format) or into the chroot's sources.list.d directory, named with the extension .list or
       .sources, depending on whether the file is in one-line or deb822 format, respectively.  If MIRROR is "-"
       then standard input is pasted into the chroot's sources.list.  More than one mirror can be specified and
       are appended to the chroot's sources.list in the given order. If you specify a https or tor MIRROR and
       you want the chroot to be able to update itself, don't forget to also install the ca-certificates
       package, the apt-transport-https package for apt versions less than 1.5 and/or the apt-transport-tor
       package using the --include option, as necessary.

       All status output is printed to standard error unless --logfile is used to redirect it to a file or
       --quiet or --silent is used to suppress any output on standard error. Help and version information will
       be printed to standard error with the --help and --version options, respectively.  Otherwise, an
       uncompressed tarball might be sent to standard output if TARGET is "-" or if no TARGET was specified.

OPTIONS

       Options are case insensitive. Short options may be bundled. Long options require a double dash and may be
       abbreviated to uniqueness. Options can be placed anywhere on the command line, even before or mixed with
       the SUITE, TARGET, and MIRROR arguments. A double dash "--" can be used to stop interpreting command line
       arguments as options to allow SUITE, TARGET and MIRROR arguments that start with a single or double dash.
       Option order only matters for options that can be passed multiple times as documented below.

       -h,--help
               Print synopsis and options of this man page and exit.

       --man   Show  the  full man page as generated from Perl POD in a pager. This requires the perldoc program
               from the perl-doc package. This is the same as running:

                   pod2man /usr/bin/mmdebstrap | man -l -

       --version
               Print the mmdebstrap version and exit.

       --variant=name
               Choose which package set to install. Valid variant names are  extract,  custom,  essential,  apt,
               required,  minbase,  buildd,  important,  debootstrap,  -,  and  standard. The default variant is
               debootstrap. See the section VARIANTS for more information.

       --mode=name
               Choose how to perform the chroot operation and create a  filesystem  with  ownership  information
               different  from  the  current  user.  Valid  mode  names are auto, sudo, root, unshare, fakeroot,
               fakechroot and chrootless.  The default mode is auto. See the section MODES for more information.

       --format=name
               Choose the output format. Valid format names are auto, directory, tar, squashfs, ext2  and  null.
               The default format is auto. See the section FORMATS for more information.

       --aptopt=option|file
               Pass  arbitrary  options  to  apt.  Will be permamently added to /etc/apt/apt.conf.d/99mmdebstrap
               inside the chroot. Use hooks for temporary  configuration  options.  Can  be  specified  multiple
               times.  Each option will be appended to 99mmdebstrap. A semicolon will be added at the end of the
               option if necessary. If the command line argument is an existing file, the content  of  the  file
               will be appended to 99mmdebstrap verbatim.

               Example: This is necessary for allowing old timestamps from snapshot.debian.org

                   --aptopt='Acquire::Check-Valid-Until "false"'
                   --aptopt='Apt::Key::gpgvcommand "/usr/libexec/mmdebstrap/gpgvnoexpkeysig"'

               Example: Settings controlling download of package description translations

                   --aptopt='Acquire::Languages { "environment"; "en"; }'
                   --aptopt='Acquire::Languages "none"'

               Example: Enable installing Recommends (by default mmdebstrap doesn't)

                   --aptopt='Apt::Install-Recommends "true"'

               Example: Configure apt-cacher or apt-cacher-ng as an apt proxy

                   --aptopt='Acquire::http { Proxy "http://127.0.0.1:3142"; }'

               Example: For situations in which the apt sandbox user cannot access the chroot

                   --aptopt='APT::Sandbox::User "root"'

               Example: Minimizing the number of packages installed from experimental

                   --aptopt='APT::Solver "aspcud"'
                   --aptopt='APT::Solver::aspcud::Preferences
                      "-count(solution,APT-Release:=/a=experimental/),-removed,-changed,-new"'

       --keyring=file|directory
               Change  the  default  keyring  to use by apt during the initial setup. This is similar to setting
               Dir::Etc::Trusted and Dir::Etc::TrustedParts using --aptopt except that the latter  setting  will
               be  permanently stored in the chroot while the keyrings passed via --keyring will only be visible
               to apt as run by mmdebstrap. Do not use --keyring if apt inside the chroot needs  to  know  about
               your  keys  after  the initial chroot creation by mmdebstrap.  This option is mainly intended for
               users who use mmdebstrap as a deboostrap drop-in replacement. As such, it is  probably  not  what
               you  want  to  use  if  you  use  mmdebstrap  with more than a single mirror unless you pass it a
               directory containing all the keyrings you need.

               By default, the local setting of Dir::Etc::Trusted and Dir::Etc::TrustedParts are used to  choose
               the keyring used by apt as run by mmdebstrap. These two locations are set to /etc/apt/trusted.gpg
               and /etc/apt/trusted.gpg.d by default. Depending on whether a file or directory is passed to this
               option,  the  former  and latter default can be changed, respectively.  Since apt only supports a
               single keyring file and directory, respectively, you can not use this  option  to  pass  multiple
               files and/or directories. Using the "--keyring" argument in the following way is equal to keeping
               the default:

                   --keyring=/etc/apt/trusted.gpg --keyring=/etc/apt/trusted.gpg.d

               If you need to pass multiple keyrings, use the "signed-by" option when specifying the mirror like
               this:

                   mmdebstrap mysuite out.tar "deb [signed-by=/path/to/key.gpg] http://..."

               Another  reason to use "signed-by" instead of --keyring is if apt inside the chroot needs to know
               by what key the repository is signed even after the initial chroot creation.

               The "signed-by" option will automatically be added to the final  "sources.list"  if  the  keyring
               required  for  the selected SUITE is not yet trusted by apt. Automatically adding the "signed-by"
               option in these cases requires "gpg" to be installed. If "gpg" and  "ubuntu-archive-keyring"  are
               installed, then you can create a Ubuntu Bionic chroot on Debian like this:

                   mmdebstrap bionic ubuntu-bionic.tar

               The   resulting  chroot  will  have  a  "source.list"  with  a  "signed-by"  option  pointing  to
               /usr/share/keyrings/ubuntu-archive-keyring.gpg.

               You do not need to use --keyring or "signed-by" if you placed the keys that  apt  needs  to  know
               about  into  /etc/apt/trusted.gpg.d  in the --setup-hook (which is before "apt update" runs), for
               example by using the copy-in special hook. You also need  to  copy  your  keys  into  the  chroot
               explicitly  if  the  key  you  passed  via "signed-by" points to a location that is not otherwise
               populated during chroot creation (for example by installing a keyring package).

       --dpkgopt=option|file
               Pass arbitrary options to dpkg. Will be permanently  added  to  /etc/dpkg/dpkg.cfg.d/99mmdebstrap
               inside  the  chroot.  Use  hooks  for  temporary configuration options. Can be specified multiple
               times. Each option will be appended to 99mmdebstrap. If the command line argument is an  existing
               file, the content of the file will be appended to 99mmdebstrap verbatim.

               Example: Exclude paths to reduce chroot size

                   --dpkgopt='path-exclude=/usr/share/man/*'
                   --dpkgopt='path-include=/usr/share/man/man[1-9]/*'
                   --dpkgopt='path-exclude=/usr/share/locale/*'
                   --dpkgopt='path-include=/usr/share/locale/locale.alias'
                   --dpkgopt='path-exclude=/usr/share/doc/*'
                   --dpkgopt='path-include=/usr/share/doc/*/copyright'
                   --dpkgopt='path-include=/usr/share/doc/*/changelog.Debian.*'

       --include=pkg1[,pkg2,...]
               Comma  or  whitespace  separated  list  of  packages  which  will be installed in addition to the
               packages installed by the specified variant. The direct and indirect hard dependencies will  also
               be  installed.  The  behaviour  of  this  option depends on the selected variant. The extract and
               custom variants install no packages by default, so for these variants, the packages specified  by
               this  option  will be the only ones that get either extracted or installed by dpkg, respectively.
               For all other variants, apt is used  to  install  the  additional  packages.  Package  names  are
               directly  passed  to  apt  and  thus,  you  can use apt features like "pkg/suite", "pkg=version",
               "pkg-", use a glob or regex for "pkg", use apt patterns or pass a path to  a  .deb  package  file
               (see  below  for  notes  concerning passing the path to a .deb package file in unshare mode). See
               apt(8) for the supported syntax.

               The option can be specified multiple times and the packages are  concatenated  in  the  order  in
               which they are given on the command line. If later list items are repeated, then they get dropped
               so that the resulting package list is free of duplicates. So the following are equivalent:

                   --include="pkg1/stable pkg2=1.0 pkg3-"
                   --include=pkg1/stable,pkg2=1.0,pkg3-,,,

                   --incl=pkg1/stable --incl="pkg2=1.0 pkg3-" --incl=pkg2=1.0,pkg3-
               Since  the  list  of  packages is separated by comma or whitespace, it is not possible to mix apt
               patterns or .deb package file paths containing either commas or whitespace  with  normal  package
               names.  If  you  do,  your  patterns  and paths will be split by comma and whitespace as well and
               become useless. To pass such a pattern or package file path, put them into  their  own  --include
               option. If the argument to --include starts with an apt pattern or with a file path, then it will
               not be split:

                   --include="?or(?priority(required), ?priority(important))"
                   --include="./path/to/deb with spaces/and,commas/foo.deb"

               Specifically, all arguments to --include that start with a "?", "!", "~", "(", "/", "./" or "../"
               are  not  split  and  treated  as  single  arguments  to  apt. To add more packages, use multiple
               --include options. To disable this detection  of  patterns  and  paths,  start  the  argument  to
               --include with a comma or whitespace.

               If you pass the path to a .deb package file using --include, mmdebstrap will ensure that the path
               exists.  If  the  path  is  a relative path, it will internally by converted to an absolute path.
               Since apt (outside the chroot) passes paths to dpkg (on the inside) verbatim, you  have  to  make
               the .deb package available under the same path inside the chroot as well or otherwise dpkg inside
               the  chroot  will  be  unable  to access it. This can be achieved using a setup-hook. A hook that
               automatically makes the contents of "file://"  mirrors  as  well  as  .deb  packages  given  with
               --include     available     inside     the     chroot    is    provided    by    mmdebstrap    as
               --hook-dir=/usr/share/mmdebstrap/hooks/file-mirror-automount. This hook takes care of copying all
               relevant file to their correct locations and cleans up those files at the end. In  unshare  mode,
               the  .deb  package  paths have to be accessible by the unshared user as well. This means that the
               package itself likely must be made world-readable and all directory components on the path to  it
               world-executable.

       --components=comp1[,comp2,...]
               Comma  or  whitespace  separated  list  of  components like main, contrib, non-free and non-free-
               firmware which will be used for all URI-only MIRROR  arguments.   The  option  can  be  specified
               multiple  times  and  the components are concatenated in the order in which they are given on the
               command line. If later list items are repeated, then they  get  dropped  so  that  the  resulting
               component list is free of duplicates. So the following are equivalent:

                   --components="main contrib non-free non-free-firmware"
                   --components=main,contrib,non-free,non-free-firmware
                   --comp=main --comp="contrib non-free" --comp="main,non-free-firmware"

       --architectures=native[,foreign1,...]
               Comma  or  whitespace  separated  list  of  architectures.  The  first architecture is the native
               architecture inside the chroot. The remaining architectures will be added  to  the  foreign  dpkg
               architectures.  Without this option, the native architecture of the chroot defaults to the native
               architecture of the system running mmdebstrap. The option can be  specified  multiple  times  and
               values  are  concatenated.  If  later  list items are repeated, then they get dropped so that the
               resulting list is free of duplicates. So the following are equivalent:

                   --architectures="amd64 armhf mipsel"
                   --architectures=amd64,armhf,mipsel
                   --arch=amd64 --arch="armhf mipsel" --arch=armhf,mipsel

       --simulate, --dry-run
               Run apt-get with --simulate. Only the package cache is initialized but  no  binary  packages  are
               downloaded  or  installed.  Use this option to quickly check whether a package selection within a
               certain suite and variant can in principle be installed as far as their dependencies go.  If  the
               output is a tarball, then no output is produced. If the output is a directory, then the directory
               will be left populated with the skeleton files and directories necessary for apt to run in it. No
               hooks are executed in with --simulate or --dry-run.

       --setup-hook=command
               Execute  arbitrary  commands  right after initial setup (directory creation, configuration of apt
               and dpkg, ...) but before any packages are downloaded or installed. At  that  point,  the  chroot
               directory  does  not contain any executables and thus cannot be chroot-ed into. See section HOOKS
               for more information.

               Example: add additional apt sources entries on top of the default ones:

                   --setup-hook='echo "deb http..." > "$1"/etc/apt/sources.list.d/custom.list'

               Example: Setup chroot for installing a sub-essential busybox-based chroot  with  --variant=custom
               --include=dpkg,busybox,libc-bin,base-files,base-passwd,debianutils

                   --setup-hook='mkdir -p "$1/bin"'
                   --setup-hook='for p in awk cat chmod chown cp diff echo env grep less ln
                       mkdir mount rm rmdir sed sh sleep sort touch uname mktemp; do
                       ln -s busybox "$1/bin/$p"; done'
                   --setup-hook='echo root:x:0:0:root:/root:/bin/sh > "$1/etc/passwd"'
                   --setup-hook='printf "root:x:0:\nmail:x:8:\nutmp:x:43:\n" > "$1/etc/group"'

               For  a  more  elegant way for setting up a sub-essential busybox-based chroot, see the --hook-dir
               option below.

       --extract-hook=command
               Execute arbitrary commands after the  Essential:yes  packages  have  been  extracted  but  before
               installing them. See section HOOKS for more information.

               Example: Install busybox symlinks

                   --extract-hook='chroot "$1" /bin/busybox --install -s'

       --essential-hook=command
               Execute  arbitrary  commands  after  the  Essential:yes  packages  have been installed but before
               installing the remaining packages. The hook is not executed for the extract and custom  variants.
               See section HOOKS for more information.

               Example: Enable unattended upgrades

                   --essential-hook='echo unattended-upgrades
                       unattended-upgrades/enable_auto_updates boolean true
                       | chroot "$1" debconf-set-selections'

               Example: Select Europe/Berlin as the timezone

                   --essential-hook='echo tzdata tzdata/Areas select Europe
                       | chroot "$1" debconf-set-selections'
                   --essential-hook='echo tzdata tzdata/Zones/Europe select Berlin
                       | chroot "$1" debconf-set-selections'

       --customize-hook=command
               Execute  arbitrary  commands after the chroot is set up and all packages got installed but before
               final cleanup actions are carried out. See section HOOKS for more information.

               Example: Add a user without a password

                   --customize-hook='chroot "$1" useradd --home-dir /home/user
                       --create-home user'
                   --customize-hook='chroot "$1" passwd --delete user'

               Example: set up /etc/hostname and /etc/hosts

                   --customize-hook='echo host > "$1/etc/hostname"'
                   --customize-hook='echo "127.0.0.1 localhost host" > "$1/etc/hosts"'

               Example: to mimic debootstrap behaviour, mmdebstrap copies from  the  host.   Remove  them  in  a
               --customize-hook to make the chroot reproducible across multiple hosts:

                   --customize-hook='rm "$1"/etc/resolv.conf'
                   --customize-hook='rm "$1"/etc/hostname'

       --hook-directory=directory
               Execute  scripts  in  directory  with  filenames starting with "setup", "extract", "essential" or
               "customize", at the respective stages  during  an  mmdebstrap  run.  The  files  must  be  marked
               executable. Their extension is ignored. Subdirectories are not traversed. This option is a short-
               hand  for specifying the remaining four hook options individually for each file in the directory.
               If there are more than one script for a stage, then they are added alphabetically. This is useful
               in cases, where a user wants to run the same hooks frequently. For  example,  given  a  directory
               "./hooks" with two scripts "setup01-foo.sh" and "setup02-bar.sh", this call:

                   mmdebstrap --customize=./scriptA --hook-dir=./hooks --setup=./scriptB

               is equivalent to this call:

                   mmdebstrap --customize=./scriptA --setup=./hooks/setup01-foo.sh \
                       --setup=./hooks/setup02-bar.sh --setup=./scriptB

               The  option  can be specified multiple times and scripts are added to the respective hooks in the
               order the options are given on the command line. Thus, if the scripts in two  directories  depend
               upon  each  other, the scripts must be placed into a common directory and be named such that they
               get added in the correct order.

               Example 1: Run mmdebstrap with eatmydata

                   --hook-dir=/usr/share/mmdebstrap/hooks/eatmydata

               Example 2: Setup chroot for installing a sub-essential busybox-based chroot

                   --hook-dir=/usr/share/mmdebstrap/hooks/busybox

               Example 3: Automatically mount all directories referenced by "file://" mirrors into the chroot

                   --hook-dir=/usr/share/mmdebstrap/hooks/file-mirror-automount

       --skip=stage[,stage,...]
               mmdebstrap tries hard to implement sensible defaults and will try to  stop  you  before  shooting
               yourself in the foot. This option is for when you are sure you know what you are doing and allows
               one  to  skip  certain  actions  and  safety checks. See section OPERATION for a list of possible
               arguments and their context. The option can be specified  multiple  times  or  you  can  separate
               multiple values by comma or whitespace.

       -q,--quiet, -s,--silent
               Do  not  write  anything  to standard error. If used together with --verbose or --debug, only the
               last option will take effect.

       -v,--verbose
               Instead of progress bars, write the dpkg and apt output  directly  to  standard  error.  If  used
               together with --quiet or --debug, only the last option will take effect.

       -d,--debug
               In addition to the output produced by --verbose, write detailed debugging information to standard
               error.  Errors  will print a backtrace. If used together with --quiet or --verbose, only the last
               option will take effect.

       --logfile=filename
               Instead of writing status information to  standard  error,  write  it  into  the  file  given  by
               filename.

MODES

       Creating  a Debian chroot requires not only permissions for running chroot but also the ability to create
       files owned by the superuser. The selected mode decides which way this is achieved.

       auto    This mode automatically selects a fitting mode. If the effective  user  id  is  the  one  of  the
               superuser, then the sudo mode is chosen. Otherwise, the unshare mode is picked if /etc/subuid and
               /etc/subgid  are  set  up  correctly.  Should  that  not be the case and if the fakechroot binary
               exists, the fakechroot mode is chosen.

       sudo, root
               This mode directly executes chroot and is the same mode of operation as is used  by  debootstrap.
               It  is  the  only mode that can directly create a directory chroot with the right permissions. If
               the chroot  directory  is  not  accessible  by  the  _apt  user,  then  apt  sandboxing  will  be
               automatically disabled. This mode needs to be able to mount and thus requires "CAP_SYS_ADMIN".

       unshare When used as a normal (not root) user, this mode uses Linux user namespaces to allow unprivileged
               use  of chroot and creation of files that appear to be owned by the superuser inside the unshared
               namespace. A tarball created in this mode will be bit-by-bit identical to a tarball created  with
               the  root  mode.  With  this  mode,  the  only  binaries  that  will run as the root user will be
               newuidmap(1)  and  newgidmap(1)  via  their  setuid  bit.  Running  those  successfully  requires
               /etc/subuid and /etc/subgid to have an entry for your username. This entry was usually created by
               adduser(8) already.

               The  unshared  user  will  not  automatically  have  access  to the same files as you do. This is
               intentional and an additional security against  unintended  changes  to  your  files  that  could
               theoretically result from running mmdebstrap and package maintainer scripts. To copy files in and
               out of the chroot, either use globally readable or writable directories or use special hooks like
               copy-in and copy-out.

               Besides  the user namespace, the mount, pid (process ids), uts (hostname) and ipc namespaces will
               be unshared as well. See the man pages of namespaces(7) and unshare(2)  as  well  as  the  manual
               pages they are linking to.

               A directory chroot created with this mode will end up with wrong ownership information (seen from
               outside  the  unshared  user namespace). For correct ownership information, the directory must be
               accessed from a user namespace with the right subuid/subgid offset, like so:

                   $ lxc-usernsexec -- lxc-unshare -s 'MOUNT|PID|UTSNAME|IPC' -- \
                   > /usr/sbin/chroot ./debian-rootfs /bin/bash

               Or without LXC:

                   $ mmdebstrap --unshare-helper /usr/sbin/chroot ./debian-rootfs /bin/bash

               Or, if you don't mind using superuser privileges and have systemd-nspawn available and  you  know
               your subuid/subgid offset (100000 in this example):

                   $ sudo systemd-nspawn --private-users=100000 \
                   > --directory=./debian-rootfs /bin/bash

               A  directory  created  in  unshare mode cannot be removed the normal way.  Instead, use something
               like this:

                   $ unshare --map-root-user --map-auto rm -rf ./debian-rootfs

               If this mode is used as the root user,  the  user  namespace  is  not  unshared  (but  the  mount
               namespace  and  other still are) and created directories will have correct ownership information.
               This is also useful in cases where the  root  user  wants  the  benefits  of  an  unshared  mount
               namespace to prevent accidentally messing up the system.

       fakeroot, fakechroot
               This mode will exec mmdebstrap again under "fakechroot fakeroot". A directory chroot created with
               this  mode  will end up with wrong permissions. If you need a directory then run mmdebstrap under
               "fakechroot fakeroot -s fakeroot.env" and use "fakeroot.env" later when entering the chroot  with
               "fakechroot  fakeroot  -i fakeroot.env chroot ...". This mode will not work if maintainer scripts
               are unable to handle "LD_PRELOAD" correctly like the package initramfs-tools until version 0.132.
               This mode will also not work with a different libc inside the chroot than on the outside. See the
               section LIMITATIONS in fakechroot(1).

       chrootless
               Uses the dpkg option "--force-script-chrootless" to install packages into TARGET without dpkg and
               apt inside TARGET but using apt and dpkg from the machine running mmdebstrap. Maintainer  scripts
               are  run  without  chrooting  into  TARGET  and rely on their dependencies being installed on the
               machine running mmdebstrap. Only very few packages support this mode. Namely, as of 2022, not all
               essential packages support it.  See  https://wiki.debian.org/Teams/Dpkg/Spec/InstallBootstrap  or
               the  dpkg-root-support usertag of debian-dpkg@lists.debian.org in the Debian bug tracking system.
               WARNING: if this option is used carelessly with packages that do not  support  "DPKG_ROOT",  this
               mode  can result in undesired changes to the system running mmdebstrap because maintainer-scripts
               will be run without chroot(1). Make sure to run this mode  without  superuser  privileges  and/or
               inside a throw-away chroot environment like so:

                   mmdebstrap --variant=apt --include=mmdebstrap \
                       --customize-hook='chroot "$1" mmdebstrap --mode=chrootless
                                         --variant=apt unstable chrootless.tar' \
                       --customize-hook='copy-out chrootless.tar .' unstable /dev/null

VARIANTS

       All  package  sets  also  include  the  direct and indirect hard dependencies (but not recommends) of the
       selected package sets. The variants minbase, buildd and -, resemble the  package  sets  that  debootstrap
       would  install  with  the same --variant argument. The release with a name matching the SUITE argument as
       well as the native architecture will be used to determine the "Essential:yes"  and  priority  values.  To
       select  packages  with  matching priority from any suite, specify the empty string for SUITE. The default
       variant is debootstrap.

       extract Installs  nothing  by  default  (not  even  "Essential:yes"  packages).  Packages  given  by  the
               "--include" option are extracted but will not be installed.

       custom  Installs  nothing  by  default  (not  even  "Essential:yes"  packages).  Packages  given  by  the
               "--include" option will be installed.  If another mode than chrootless was selected and dpkg  was
               not part of the included package set, then this variant will fail because it cannot configure the
               packages.

       essential
               "Essential:yes"  packages.  If  SUITE  is a non-empty string, then only packages from the archive
               with suite or codename matching  SUITE  will  be  considered  for  selection  of  "Essential:yes"
               packages.

       apt     The  essential  set  plus apt. This variant uses the fact that apt treats itself as essential and
               thus running "apt-get dist-upgrade" without any packages installed will install the essential set
               plus apt. If you just want essential and  apt,  then  this  variant  is  faster  than  using  the
               essential  variant and adding apt via "--include" because all packages get installed at once. The
               downside of this variant is,  that  if  it  should  happen  that  an  essential  package  is  not
               installable, then it will just get ignored without throwing an error.

       buildd  The  essential  set plus apt and build-essential.  It is roughly equivalent to running mmdebstrap
               with

                   --variant=essential --include="apt,build-essential"

       required, minbase
               The essential set plus all packages with Priority:required.  It is roughly equivalent to  running
               mmdebstrap with

                   --variant=essential --include="?priority(required)"

       important, debootstrap, -
               The  required  set plus all packages with Priority:important. This is the default of debootstrap.
               It is roughly equivalent to running mmdebstrap with

                   --variant=essential --include="~prequired|~pimportant"

       standard
               The important set plus all packages with Priority:standard.  It is roughly equivalent to  running
               mmdebstrap with

                   --variant=essential --include="~prequired|~pimportant|~pstandard"

FORMATS

       The  output format of mmdebstrap is specified using the --format option.  Without that option the default
       format is auto. The following formats exist:

       auto    When selecting this format (the default), the actual format will  be  inferred  from  the  TARGET
               positional  argument.  If TARGET was not specified, then the tar format will be chosen. If TARGET
               happens to be /dev/null or if standard output is /dev/null, then the null format will be  chosen.
               If  TARGET is an existing directory, and does not equal to "-", then the directory format will be
               chosen. If TARGET ends with ".tar" or with one of the filename extensions listed in  the  section
               COMPRESSION,  or  if  TARGET  equals  "-",  or if TARGET is a named pipe (fifo) or if TARGET is a
               character special file, then the tar format will be chosen. If TARGET ends  with  ".squashfs"  or
               ".sqfs",  then  the  squashfs  format  will  be chosen. If TARGET ends with ".ext2" then the ext2
               format will be chosen. If none of these conditions apply, the directory format will be chosen.

       directory, dir
               A chroot directory will be created in TARGET.  If the directory already exists, it must either be
               empty or only contain an empty "lost+found" directory.  The special TARGET "-" does not work with
               this format because a directory cannot be written to standard output. If you need your  directory
               be  named  "-",  then  just  explicitly pass the relative path to it like ./-.  If a directory is
               chosen as output in any other mode than  sudo,  then  its  contents  will  have  wrong  ownership
               information  and  special  device  files  will  be  missing.  Refer to the section MODES for more
               information.

       tar     A temporary chroot directory will be created in $TMPDIR or /tmp if $TMPDIR is not set. A  tarball
               of that directory will be stored in TARGET or sent to standard output if TARGET was omitted or if
               TARGET  equals  "-".   If  TARGET  ends with one of the filename extensions listed in the section
               COMPRESSION, then a compressed tarball will be created. The tarball will be in POSIX  1003.1-2001
               (pax) format and will contain extended attributes.  To preserve the extended attributes, you have
               to pass --xattrs --xattrs-include='*' to tar when extracting the tarball.

       squashfs, sqfs
               A  temporary chroot directory will be created in $TMPDIR or /tmp if $TMPDIR is not set. A tarball
               of that directory will be piped to the "tar2sqfs" utility, which will  create  an  xz  compressed
               squashfs image with a blocksize of 1048576 bytes in TARGET.  The special TARGET "-" does not work
               with  this  format because "tar2sqfs" can only write to a regular file. If you need your squashfs
               image be named "-", then just explicitly pass the relative path to it like  ./-.  The  "tar2sqfs"
               tool  only  supports a limited set of extended attribute prefixes. Therefore, extended attributes
               are disabled in the resulting image. If you need them, create a  tarball  first  and  remove  the
               extended attributes from its pax headers. Refer to the EXAMPLES section for how to achieve this.

       ext2    A  temporary chroot directory will be created in $TMPDIR or /tmp if $TMPDIR is not set. A tarball
               of that directory will be piped to the "genext2fs" utility, which will create an ext2 image  that
               will  be approximately 90% full in TARGET.  The special TARGET "-" does not work with this format
               because "genext2fs" can only write to a regular file. If you need your ext2 image be  named  "-",
               then  just  explicitly  pass  the  relative path to it like ./-. To convert the result to an ext3
               image, use "tune2fs  -O  has_journal  TARGET"  and  to  convert  it  to  ext4,  use  "tune2fs  -O
               extents,uninit_bg,dir_index,has_journal  TARGET".  Since  "genext2fs"  does  not support extended
               attributes, the resulting image will not contain them.

       null    A temporary chroot directory will be created in $TMPDIR or /tmp if $TMPDIR is not set. After  the
               bootstrap  is  complete,  the  temporary chroot will be deleted without being part of the output.
               This is most useful when  the  desired  artifact  is  generated  inside  the  chroot  and  it  is
               transferred  using special hooks such as sync-out. It is also useful in situations where only the
               exit code or stdout or stderr of a process run in a hook is of interest.

HOOKS

       This section describes properties of the hook options --setup-hook, --extract-hook, --essential-hook  and
       --customize-hook  which  are  common  to  all  four  of  them.  Any  information specific to each hook is
       documented under the specific hook options in the section OPTIONS.

       The options can be specified multiple times and the commands are executed in the order in which they  are
       given  on  the  command  line.  There  are four different types of hook option arguments. If the argument
       passed to the hook option starts with "copy-in", "copy-out", "tar-in", "tar-out", "upload" or  "download"
       followed by a space, then the hook is interpreted as a special hook. Otherwise, if command is an existing
       executable  file  from  $PATH  or  if  command does not contain any shell metacharacters, then command is
       directly exec-ed with the path to the chroot directory passed as the first argument.  Otherwise,  command
       is  executed  under sh and the chroot directory can be accessed via $1. Most environment variables set by
       mmdebstrap (like "DEBIAN_FRONTEND", "LC_ALL" and "PATH") are preserved.  Most  notably,  "APT_CONFIG"  is
       being  unset.  If  you  need  the  path  to  "APT_CONFIG" as written by mmdebstrap it can be found in the
       "MMDEBSTRAP_APT_CONFIG" environment variable. All environment variables set by the  user  are  preserved,
       except  for  "TMPDIR" which is cleared. See section TMPDIR. Furthermore, "MMDEBSTRAP_MODE" will store the
       mode set by --mode, "MMDEBSTRAP_FORMAT" stores the format chosen by  --format,  "MMDEBSTRAP_HOOK"  stores
       which hook is currently run (setup, extract, essential, customize), "MMDEBSTRAP_ARGV0" stores the name of
       the  binary  with which mmdebstrap was executed and "MMDEBSTRAP_VERBOSITY" stores the numerical verbosity
       level (0 for no output, 1 for normal, 2 for verbose and 3 for  debug  output).  The  "MMDEBSTRAP_INCLUDE"
       variable stores the list of packages, apt patterns or file paths given by the --include option, separated
       by a comma and with commas and percent signs in the option values urlencoded. If SUITE name was supplied,
       it's stored in "MMDEBSTRAP_SUITE".

       In special hooks, the paths inside the chroot are relative to the root directory of the chroot.  The path
       on  the  outside  is relative to current directory of the original mmdebstrap invocation. The path inside
       the chroot must already exist. Paths outside the chroot are created as necessary.

       In fakechroot mode, "tar", or "sh" and "cat" have to be run inside the chroot or otherwise, symlinks will
       be wrongly resolved and/or permissions will be off. This means that  the  special  hooks  might  fail  in
       fakechroot  mode  for the setup hook or for the extract and custom variants if no "tar" or "sh" and "cat"
       is available inside the chroot.

       copy-out pathinside [pathinside ...] pathoutside
               Recursively copies one or more files and  directories  recursively  from  pathinside  inside  the
               chroot to pathoutside outside of the chroot.

       copy-in pathoutside [pathoutside ...] pathinside
               Recursively  copies  one  or  more  files and directories into the chroot into, placing them into
               pathinside inside of the chroot.

       sync-out pathinside pathoutside
               Recursively copy everything inside pathinside inside the chroot into pathoutside. In contrast  to
               copy-out,  this  command  synchronizes  the content of pathinside with the content of pathoutside
               without deleting anything from pathoutside but overwriting content as necessary. Use this command
               over copy-out if you don't want to create a new directory outside the chroot but only update  the
               content of an existing directory.

       sync-in pathoutside pathinside
               Recursively  copy everything inside pathoutside into pathinside inside the chroot. In contrast to
               copy-in, this command synchronizes the content of pathoutside  with  the  content  of  pathinside
               without  deleting anything from pathinside but overwriting content as necessary. Use this command
               over copy-in if you don't want to create a new directory inside the chroot but  only  update  the
               content of an existing directory.

       tar-in outside.tar pathinside
               Unpacks  a  tarball outside.tar from outside the chroot into a certain location pathinside inside
               the chroot. In unshare mode, device nodes cannot be created. To ignore device nodes in  tarballs,
               use --skip=tar-in/mknod.

       tar-out pathinside outside.tar
               Packs  the  path  pathinside  from  inside  the  chroot into a tarball, placing it into a certain
               location outside.tar outside the chroot.

       download fileinside fileoutside
               Copy the file given by fileinside from inside the chroot to outside the chroot as fileoutside. In
               contrast to copy-out, this command only handles files and not directories. To  copy  a  directory
               recursively  out  of the chroot, use copy-out or tar-out. Its advantage is, that by being able to
               specify the full path on the outside, including the filename, the file on the outside can have  a
               different  name  from  the  file on the inside. In contrast to copy-out and tar-out, this command
               follows symlinks.

       upload fileoutside fileinside
               Copy the file given by fileoutside from outside the chroot to inside the chroot as fileinside. In
               contrast to copy-in, this command only handles files and not directories.  To  copy  a  directory
               recursively  into  the  chroot,  use  copy-in  or tar-in. Its advantage is, that by being able to
               specify the full path on the inside, including the filename, the file on the inside  can  have  a
               different  name  from  the file on the outside. In contrast to copy-in and tar-in, permission and
               ownership information will not be retained.

OPERATION

       This section gives an overview of the different steps to create a chroot. At its  core,  what  mmdebstrap
       does can be put into a 14 line shell script:

           mkdir -p "$2/etc/apt" "$2/var/cache" "$2/var/lib"
           cat << END > "$2/apt.conf"
           Apt::Architecture "$(dpkg --print-architecture)";
           Apt::Architectures "$(dpkg --print-architecture)";
           Dir "$(cd "$2" && pwd)";
           Dir::Etc::Trusted "$(eval "$(apt-config shell v Dir::Etc::Trusted/f)"; printf "$v")";
           Dir::Etc::TrustedParts "$(eval "$(apt-config shell v Dir::Etc::TrustedParts/d)"; printf "$v")";
           END
           echo "deb http://deb.debian.org/debian/ $1 main" > "$2/etc/apt/sources.list"
           APT_CONFIG="$2/apt.conf" apt-get update
           APT_CONFIG="$2/apt.conf" apt-get --yes --download-only install '?essential'
           for f in "$2"/var/cache/apt/archives/*.deb; do dpkg-deb --extract "$f" "$2"; done
           chroot "$2" sh -c "dpkg --install --force-depends /var/cache/apt/archives/*.deb"

       The  additional complexity of mmdebstrap is to support operation without superuser privileges, bit-by-bit
       reproducible output, hooks and foreign architecture support.

       The remainder of this section explains what mmdebstrap does step-by-step.

       check   Upon startup, several checks are carried out, like:

               •   whether required utilities (apt, dpkg, tar) are installed

               •   which mode to use and whether prerequisites are met

               •   do not allow chrootless mode as root (without fakeroot) unless inside a  chroot.  This  check
                   can be disabled using --skip=check/chrootless

               •   whether   the  requested  architecture  can  be  executed  (requires  arch-test)  using  qemu
                   binfmt_misc support. This requires arch-test and can be disabled using --skip=check/qemu

               •   how the apt sources can be assembled from SUITE, MIRROR and --components and/or from standard
                   input as deb822 or one-line format and whether the required GPG keys exist.

               •   which output format to pick depending on the --format argument or name of TARGET or its type.

               •   whether the output directory is empty. This check can be disabled using --skip=check/empty

               •   whether adding a "signed-by" to "apt/sources.list" is necessary. This requires gpg and can be
                   disabled using --skip=check/signed-by

       setup   The following tasks are carried out unless --skip=setup is used:

               •   create required directories

               •   write out the temporary apt config file

               •   populates /etc/apt/apt.conf.d/99mmdebstrap and /etc/dpkg/dpkg.cfg.d/99mmdebstrap with  config
                   options from --aptopt and --dpkgopt, respectively

               •   write out /etc/apt/sources.list

               •   copy over /etc/resolv.conf and /etc/hostname

               •   populate /dev if mknod is possible

       setup-hook
               Run --setup-hook options and all setup* scripts in --hook-dir.

       update  Runs  "apt-get update" using the temporary apt configuration file created in the setup step. This
               can be disabled using --skip=update.

       download
               In the extract and custom variants, "apt-get install"  is  used  to  download  all  the  packages
               requested  via  the  --include option. The apt variant uses the fact that libapt treats the "apt"
               packages as implicitly essential to download only all "Essential:yes"  packages  plus  apt  using
               "apt-get  dist-upgrade".  In  the remaining variants, all Packages files downloaded by the update
               step are inspected to find the "Essential:yes" package  set  as  well  as  all  packages  of  the
               required priority. If SUITE is a non-empty string, then only packages from the archive with suite
               or codename matching SUITE will be considered for selection of "Essential:yes" packages.

       mount   Mount relevant device nodes, /proc and /sys into the chroot and unmount them afterwards. This can
               be    disabled    using   --skip=chroot/mount   or   specifically   by   --skip=chroot/mount/dev,
               --skip=chroot/mount/proc  and  --skip=chroot/mount/sys,  respectively.  mmdebstrap  will  disable
               running  services  by temporarily moving /usr/sbin/policy-rc.d and /usr/sbin/start-stop-daemon if
               they    exist.    This     can     be     disabled     with     --skip=chroot/policy-rc.d     and
               --skip=chroot/start-stop-daemon, respectively.

       extract Extract the downloaded packages into the rootfs.

       prepare In fakechroot mode, environment variables "LD_LIBRARY_PATH" will be set up correctly. For foreign
               fakechroot environments, "LD_LIBRARY_PATH" and "QEMU_LD_PREFIX" are set up accordingly. This step
               is not carried out in extract mode and neither for the chrootless variant.

       extract-hook
               Run --extract-hook options and all extract* scripts in --hook-dir.

       essential
               Uses  "dpkg  --install" to properly install all packages that have been extracted before. Removes
               all  packages  downloaded  in  the  download  step,  except   those   which   were   present   in
               /var/cache/apt/archives/  before  (if  any).  This can be disabled using --skip=essential/unlink.
               This step is not carried out in extract mode.

       essential-hook
               Run --essential-hook options and all essential* scripts in --hook-dir.  This step is not  carried
               out in extract mode.

       install Install  the apt package into the chroot, if necessary and then run apt from inside the chroot to
               install all remaining packages. This step is not carried out in extract mode.

       customize-hook
               Run --customize-hook options and all customize* scripts in --hook-dir.  This step is not  carried
               out in extract mode.

       unmount Unmount everything that was mounted during the mount stage and restores /usr/sbin/policy-rc.d and
               /usr/sbin/start-stop-daemon if necessary.

       cleanup Performs cleanup tasks, unless --skip=cleanup is used:

               •   Removes   the   package   lists  (unless  --skip=cleanup/apt/lists)  and  apt  cache  (unless
                   --skip=cleanup/apt/cache). Both removals can be disabled by using --skip=cleanup/apt.

               •   Remove  all  files   that   were   put   into   the   chroot   for   setup   purposes,   like
                   /etc/apt/apt.conf.d/00mmdebstrap  and  the  temporary  apt config. This can be disabled using
                   --skip=cleanup/mmdebstrap.

               •   Remove  files  that  make  the  result  unreproducible  and  write  the   empty   string   to
                   /etc/machine-id  if  it  exists. This can be disabled using --skip=cleanup/reproducible. Note
                   that this will not remove  files  that  make  the  result  unreproducible  on  machines  with
                   differing  /etc/resolv.conf  or /etc/hostname. Use a --customize-hook to make those two files
                   reproducible across multiple hosts. See section "SOURCE_DATE_EPOCH" for more information. The
                   following files will be removed:

                   •   /var/log/dpkg.log/var/log/apt/history.log/var/log/apt/term.log/var/log/alternatives.log/var/cache/ldconfig/aux-cache/var/log/apt/eipp.log.xz/var/lib/dbus/machine-id

               •   Remove everything in /run inside the chroot. This can be disabled using --skip=cleanup/run.

               •   Remove everything in /tmp inside the chroot. This can be disabled using --skip=cleanup/tmp.

       output  For formats other than directory, pack up the temporary chroot directory  into  a  tarball,  ext2
               image or squashfs image and delete the temporary chroot directory.

               If  --skip=output/dev  is  added,  the  resulting  chroot  will  not  contain  the  device nodes,
               directories and symlinks that debootstrap creates but just an empty  /dev  as  created  by  base-
               files.

               If  --skip=output/mknod  is  added,  the  resulting chroot will not contain device nodes (neither
               block nor character special devices). This is useful if the chroot tarball is to be exatracted in
               environments where mknod does not function like in unshared user namespaces.

EXAMPLES

       Use like debootstrap:

           $ sudo mmdebstrap unstable ./unstable-chroot

       Without superuser privileges:

           $ mmdebstrap unstable unstable-chroot.tar

       With no command line arguments at all. The chroot content is entirely defined by a sources.list  file  on
       standard input.

           $ mmdebstrap < /etc/apt/sources.list > unstable-chroot.tar

       Since  the  tarball  is output on stdout, members of it can be excluded using tar on-the-fly. For example
       the /dev directory can be removed from the final tarbal in cases where it is to be extracted  by  a  non-
       root user who cannot create device nodes:

           $ mmdebstrap unstable | tar --delete ./dev > unstable-chroot.tar

       Create a tarball for use with "sbuild --chroot-mode=unshare":

           $ mmdebstrap --variant=buildd unstable ~/.cache/sbuild/unstable-amd64.tar

       Instead of a tarball, a squashfs image can be created:

           $ mmdebstrap unstable unstable-chroot.squashfs

       By  default, mmdebstrap runs tar2sqfs with "--no-skip --exportable --compressor xz --block-size 1048576".
       To choose a different set of options, and  to  filter  out  all  extended  attributes  not  supported  by
       tar2sqfs, pipe the output of mmdebstrap into tar2sqfs manually like so:

           $ mmdebstrap unstable \
               | mmtarfilter --pax-exclude='*' \
                   --pax-include='SCHILY.xattr.user.*' \
                   --pax-include='SCHILY.xattr.trusted.*' \
                   --pax-include='SCHILY.xattr.security.*' \
               | tar2sqfs --quiet --no-skip --force --exportable --compressor xz \
                   --block-size 1048576 unstable-chroot.squashfs

       By  default,  debootstrapping  a  stable  distribution  will  add mirrors for security and updates to the
       sources.list.

           $ mmdebstrap stable stable-chroot.tar

       If you don't want this behaviour, you can  override  it  by  manually  specifying  a  mirror  in  various
       different ways:

           $ mmdebstrap stable stable-chroot.tar http://deb.debian.org/debian
           $ mmdebstrap stable stable-chroot.tar "deb http://deb.debian.org/debian stable main"
           $ mmdebstrap stable stable-chroot.tar /path/to/sources.list
           $ mmdebstrap stable stable-chroot.tar - < /path/to/sources.list

       Drop locales (but not the symlink to the locale name alias database), translated manual packages (but not
       the untranslated ones), and documentation (but not copyright and Debian changelog).

           $ mmdebstrap --variant=essential \
               --dpkgopt='path-exclude=/usr/share/man/*' \
               --dpkgopt='path-include=/usr/share/man/man[1-9]/*' \
               --dpkgopt='path-exclude=/usr/share/locale/*' \
               --dpkgopt='path-include=/usr/share/locale/locale.alias' \
               --dpkgopt='path-exclude=/usr/share/doc/*' \
               --dpkgopt='path-include=/usr/share/doc/*/copyright' \
               --dpkgopt='path-include=/usr/share/doc/*/changelog.Debian.*' \
               unstable debian-unstable.tar

       Create a bootable USB Stick that boots into a full Debian desktop:

           $ mmdebstrap --aptopt='Apt::Install-Recommends "true"' --customize-hook \
               'chroot "$1" adduser --gecos user --disabled-password user' \
               --customize-hook='echo 'user:live' | chroot "$1" chpasswd' \
               --customize-hook='echo host > "$1/etc/hostname"' \
               --customize-hook='echo "127.0.0.1 localhost host" > "$1/etc/hosts"' \
               --include=linux-image-amd64,task-desktop unstable debian-unstable.tar
           $ cat << END > extlinux.conf
           > default linux
           > timeout 0
           >
           > label linux
           > kernel /vmlinuz
           > append initrd=/initrd.img root=LABEL=rootfs
           END
           # You can use $(sudo blockdev --getsize64 /dev/sdXXX) to get the right
           # image size for the target medium in bytes
           $ guestfish -N debian-unstable.img=disk:8G -- \
               part-disk /dev/sda mbr : \
               part-set-bootable /dev/sda 1 true : \
               mkfs ext4 /dev/sda1 : \
               set-label /dev/sda1 rootfs : \
               mount /dev/sda1 / : \
               tar-in debian-unstable.tar / xattrs:true : \
               upload /usr/lib/EXTLINUX/mbr.bin /boot/mbr.bin : \
               copy-file-to-device /boot/mbr.bin /dev/sda size:440 : \
               extlinux / : copy-in extlinux.conf / : sync : umount / : shutdown
           $ qemu-system-x86_64 -m 1G -enable-kvm debian-unstable.img
           $ sudo dd if=debian-unstable.img of=/dev/sdXXX status=progress

       On architectures without extlinux you can also boot using grub2:

           $ mmdebstrap --include=linux-image-amd64,grub2,systemd-sysv unstable fs.tar
           $ guestfish -N debian-unstable.img=disk:2G -- \
               part-disk /dev/sda mbr : \
               part-set-bootable /dev/sda 1 true : \
               mkfs ext4 /dev/sda1 : \
               set-label /dev/sda1 rootfs : \
               mount /dev/sda1 / : \
               tar-in fs.tar / xattrs:true : \
               command "grub-install /dev/sda" : \
               command update-grub : \
               sync : umount / : shutdown
           $ qemu-system-x86_64 -m 1G -enable-kvm debian-unstable.img

       Build  libdvdcss2.deb  without  installing  installing  anything  or  changing apt sources on the current
       system:

           $ mmdebstrap --variant=apt --components=main,contrib --include=libdvd-pkg \
               --customize-hook='chroot $1 /usr/lib/libdvd-pkg/b-i_libdvdcss.sh' \
               | tar --extract --verbose --strip-components=4 \
                   --wildcards './usr/src/libdvd-pkg/libdvdcss2_*_*.deb'
           $ ls libdvdcss2_*_*.deb

       Use as replacement for autopkgtest-build-qemu and vmdb2 for  all  architectures  supporting  EFI  booting
       (amd64, arm64, armhf, i386, riscv64), use a convenience wrapper around mmdebstrap:

           $ mmdebstrap-autopkgtest-build-qemu unstable ./autopkgtest.img

       Use  as  replacement for autopkgtest-build-qemu and vmdb2 on architectures supporting extlinux (amd64 and
       i386):

           $ mmdebstrap --variant=important --include=linux-image-amd64 \
               --customize-hook='chroot "$1" passwd --delete root' \
               --customize-hook='chroot "$1" useradd --home-dir /home/user --create-home user' \
               --customize-hook='chroot "$1" passwd --delete user' \
               --customize-hook='echo host > "$1/etc/hostname"' \
               --customize-hook='echo "127.0.0.1 localhost host" > "$1/etc/hosts"' \
               --customize-hook=/usr/share/autopkgtest/setup-commands/setup-testbed \
               unstable debian-unstable.tar
           $ cat << END > extlinux.conf
           > default linux
           > timeout 0
           >
           > label linux
           > kernel /vmlinuz
           > append initrd=/initrd.img root=/dev/vda1 rw console=ttyS0
           END
           $ guestfish -N debian-unstable.img=disk:8G -- \
               part-disk /dev/sda mbr : \
               part-set-bootable /dev/sda 1 true : \
               mkfs ext4 /dev/sda1 : mount /dev/sda1 / : \
               tar-in debian-unstable.tar / xattrs:true : \
               upload /usr/lib/EXTLINUX/mbr.bin /boot/mbr.bin : \
               copy-file-to-device /boot/mbr.bin /dev/sda size:440 : \
               extlinux / : copy-in extlinux.conf / : sync : umount / : shutdown
           $ qemu-img convert -O qcow2 debian-unstable.img debian-unstable.qcow2

       As a debootstrap wrapper to run it without superuser privileges but using Linux user namespaces  instead.
       This fixes Debian bug #829134.

           $ mmdebstrap --variant=custom --mode=unshare \
               --setup-hook='debootstrap unstable "$1"' \
               - debian-debootstrap.tar

       Build a non-Debian chroot like Ubuntu bionic:

           $ mmdebstrap --aptopt='Dir::Etc::Trusted
              "/usr/share/keyrings/ubuntu-keyring-2012-archive.gpg"' bionic bionic.tar

       If,  for  some  reason,  you cannot use a caching proxy like apt-cacher or apt-cacher-ng, you can use the
       sync-in  and  sync-out  special  hooks   to   synchronize   a   directory   outside   the   chroot   with
       /var/cache/apt/archives inside the chroot.

           $ mmdebstrap --variant=apt --skip=essential/unlink \
               --setup-hook='mkdir -p ./cache "$1"/var/cache/apt/archives/' \
               --setup-hook='sync-in ./cache /var/cache/apt/archives/' \
               --customize-hook='sync-out /var/cache/apt/archives ./cache' \
               unstable /dev/null

       Instead  of  copying  potentially  large  amounts  of  data with sync-in you can also use a bind-mount in
       combination with a "file://" mirror to make packages from the outside available inside the chroot:

           $ mmdebstrap --variant=apt --skip=essential/unlink \
               --setup-hook='mkdir "$1/tmp/mirror"' \
               --setup-hook='mount -o ro,bind /tmp/mirror "$1/tmp/mirror"' \
               --customize-hook='sync-out /var/cache/apt/archives ./cache' \
               --customize-hook='umount "$1/tmp/mirror"; rmdir "$1/tmp/mirror";' \
               unstable /dev/null file:///tmp/mirror http://deb.debian.org/debian

       To automatically mount all directories referenced by "file://" mirrors into the  chroot  you  can  use  a
       hook:

           $ mmdebstrap --variant=apt \
               --hook-dir=/usr/share/mmdebstrap/hooks/file-mirror-automount \
               unstable /dev/null file:///tmp/mirror1 file:///tmp/mirror2

       Create a system that can be used with docker:

           $ mmdebstrap unstable | sudo docker import - debian
           [...]
           $ sudo docker run -it --rm debian whoami
           root
           $ sudo docker rmi debian

       Create  and  boot  a  qemu  virtual  machine for an arbitrary architecture using the debvm-create wrapper
       script around mmdebstrap:

           $ debvm-create -r stable -- --architecture=riscv64
           $ debvm-run

       Create a system that can be used with podman:

           $ mmdebstrap unstable | podman import - debian
           [...]
           $ podman run --network=none -it --rm debian whoami
           root
           $ podman rmi debian

       As a docker/podman replacement:

           $ mmdebstrap unstable chroot.tar
           [...]
           $ mmdebstrap --variant=custom --skip=update,tar-in/mknod \
               --setup-hook='tar-in chroot.tar /' \
               --customize-hook='chroot "$1" whoami' unstable /dev/null
           [...]
           root
           $ rm chroot.tar

       You can re-use a chroot tarball created with mmdebstrap for further refinement.  Say you want to create a
       minimal chroot and a chroot with more packages installed, then instead of downloading and installing  the
       essential packages twice you can instead build on top of the already present minimal chroot:

           $ mmdebstrap --variant=apt unstable chroot.tar
           $ mmdebstrap --variant=custom --skip=update,setup,cleanup,tar-in/mknod \
               --setup-hook='tar-in chroot.tar /' \
               --customize-hook='chroot "$1" apt-get install --yes pkg1 pkg2' \
               '' chroot-full.tar

ENVIRONMENT VARIABLES

       "SOURCE_DATE_EPOCH"
               By setting "SOURCE_DATE_EPOCH" the result will be reproducible across multiple runs with the same
               options  and  mirror  content.  Note that for debootstrap compatibility, mmdebstrap will copy the
               host's /etc/resolv.conf and /etc/hostname into the chroot. This means that the mmdebstrap  output
               will  differ if it is run on machines with differing /etc/resolv.conf and /etc/hostname contents.
               To make the result reproducible across different hosts, you need to manually either  delete  both
               files from the output:

                   $ mmdebstrap --customize-hook='rm "$1"/etc/resolv.conf' \
                                --customize-hook='rm "$1"/etc/hostname' ...

               or fill them with reproducible content:

                   $ mmdebstrap --customize-hook='echo nameserver X > "$1"/etc/resolv.conf' \
                                --customize-hook='echo host > "$1"/etc/hostname' ...

       "TMPDIR"
               When creating a tarball, a temporary directory is populated with the rootfs before the tarball is
               packed.  The  location  of that temporary directory will be in /tmp or the location pointed to by
               "TMPDIR" if that environment variable is set. Setting "TMPDIR" to a different directory than /tmp
               is useful if you have /tmp on a tmpfs that is too small for your rootfs.

               If you set "TMPDIR" in unshare mode, then the unshared user must be able to access the directory.
               This means that the directory itself must be world-writable and all  its  ancestors  must  be  at
               least world-executable.

               Since  "TMPDIR"  is  only valid outside the chroot, the variable is being unset when running hook
               scripts. If you need a valid temporary directory in a  hook,  consider  using  /tmp  inside  your
               target directory.

DEBOOTSTRAP

       This section lists some differences to debootstrap.

       •       More than one mirror possible

       •       Default mirrors for stable releases include updates and security mirror

       •       Multiple ways to operate as non-root: fakechroot and unshare

       •       twice as fast

       •       Can create a chroot with only "Essential:yes" packages and their deps

       •       Reproducible output by default if $SOURCE_DATE_EPOCH is set

       •       Can create output on filesystems with nodev set

       •       apt cache and lists are cleaned at the end

       •       foreign architecture chroots using qemu-user

       Limitations in comparison to debootstrap:

       •       Only runs on systems with apt installed (Debian and derivatives)

       •       No SCRIPT argument (use hooks instead)

       •       Some debootstrap options don't exist, namely:

               --second-stage, --exclude, --resolve-deps, --force-check-gpg, --merged-usr and --no-merged-usr

MERGED-/USR

       mmdebstrap  will  create a merged-/usr chroot or not depending on whether packages setting up merged-/usr
       (i.e. the usrmerge package) are installed or not. In Debian, the  essential  package  init-system-helpers
       depends on the usrmerge package, starting with Debian 12 (Bookworm).

       Before  Debian  12  (Bookworm),  to  force mmdebstrap to create a chroot with merged-/usr using symlinks,
       either explicitly install the usrmerge package:

           --include=usrmerge

       or setup merged-/usr using the debootstrap-method which takes care of the architecture specific  symlinks
       and installs the usr-is-merged package.

           --hook-dir=/usr/share/mmdebstrap/hooks/merged-usr

       To  force  mmdebstrap to create a chroot without merged-/usr even after the Debian 12 (Bookworm) release,
       you can use the following hook:

           --hook-dir=/usr/share/mmdebstrap/hooks/no-merged-usr

       This   will    write    "this    system    will    not    be    supported    in    the    future"    into
       /etc/unsupported-skip-usrmerge-conversion  inside  the  chroot  and  install the usr-is-merged package to
       avoid the installation of the usrmerge package and its dependencies.

       If you are using mmdebstrap in a setup where you do not know upfront whether the chroot you are  creating
       should  be  merged-/usr  or  not  and  you  want  to  avoid installation of the usrmerge package and it's
       dependencies, you can use:

           --hook-dir=/usr/share/mmdebstrap/hooks/maybe-merged-usr

       That hook will use the availability of the usr-is-merged package to decide whether to call the merged-usr
       hook or not.

COMPRESSION

       mmdebstrap will choose a suitable compressor for the output tarball depending on the filename  extension.
       The following mapping from filename extension to compressor applies:

        extension compressor
        --------------------
        .tar      none
        .gz       gzip
        .tgz      gzip
        .taz      gzip
        .Z        compress
        .taZ      compress
        .bz2      bzip2
        .tbz      bzip2
        .tbz2     bzip2
        .tz2      bzip2
        .lz       lzip
        .lzma     lzma
        .tlz      lzma
        .lzo      lzop
        .lz4      lz4
        .xz       xz
        .txz      xz
        .zst      zstd

       To  change  compression  specific options, either use the respecitve environment variables like XZ_OPT or
       send mmdebstrap output to your compressor of choice with a pipe.

WRAPPERS

   debvm
       debvm helps create and run virtual machines for various Debian  releases  and  architectures.   The  tool
       debvm-create can be used to create a virtual machine image and the tool debvm-run can be used to run such
       a  machine  image.  Their  purpose  primarily is testing software using qemu as a containment technology.
       These are relatively thin wrappers around mmdebstrap and qemu.

   bdebstrap
       bdebstrap is a YAML config based multi-mirror Debian chroot creation tool.  bdebstrap is  an  alternative
       to debootstrap and a wrapper around mmdebstrap to support YAML based configuration files. It inherits all
       benefits  from  mmdebstrap. The support for configuration allows storing all customization in a YAML file
       instead of having  to  use  a  very  long  one-liner  call  to  mmdebstrap.  It  also  layering  multiple
       customizations on top of each other, e.g. to support flavors of an image.

BUGS

       https://gitlab.mister-muffin.de/josch/mmdebstrap/issues

       https://bugs.debian.org/src:mmdebstrap

       As  of version 1.20.9, dpkg does not provide facilities preventing it from reading the dpkg configuration
       of the machine running mmdebstrap.  Therefore, until this  dpkg  limitation  is  fixed,  a  default  dpkg
       configuration  is recommended on machines running mmdebstrap. If you are using mmdebstrap as the non-root
       user, then as a workaround you could run "chmod 600 /etc/dpkg/dpkg.cfg.d/*" so that the config files  are
       only accessible by the root user. See Debian bug #808203.

       With  apt  versions before 2.1.16, setting "[trusted=yes]" or "Acquire::AllowInsecureRepositories "1"" to
       allow signed archives without a known public key or unsigned archives will fail because of a gpg  warning
       in  the  apt  output.  Since  apt does not communicate its status via any other means than human readable
       strings, and because mmdebstrap wants to treat transient network errors as errors, mmdebstrap treats  any
       warning from "apt-get update" as an error.

SEE ALSO

       debootstrap(8), debvm(1), bdebstrap(1)

perl v5.38.2                                       2024-02-26                                      MMDEBSTRAP(1)