SquashFS ======== ``conda-pack`` can package environments into `SquashFS `_, a compressed, read-only Linux filesystem. These filesystems can then be mounted directly, without decompressing them first. This allows using packed environments immediately and without consuming disk space. Packing ------- Packing environments into SquashFS works on MacOS and Linux. You will need to install `squashfs-tools `_, more specifically the ``mksquashfs`` command. On Ubuntu run ``apt-get install squashfs-tools``, on MacOS ``brew install squashfs`` or alternatively (Linux+MacOS) install from conda-forge through ``conda install -c conda-forge squashfs-tools``. Mounting -------- Mounting SquashFS environments is only possible on MacOS and Linux. On Linux there are two ways: - Mounting directly: Since SquashFS is part of the Linux kernel, it can be mounted using ``mount -t squashfs ``. This will require root or ``CAP_SYS_ADMIN``. - Mounting as `Filesystem in Userspace (FUSE) `_: This can be done by installing `squashfuse `_, for example through ``apt-get install squashfuse`` (Ubuntu), ``conda install -c conda-forge squashfuse`` or from source. Contrary to the Kernel-version of SquashFS, ``squashfuse`` doesn't require root permissions to run. ``squashfuse_ll`` comes packaged with ``squashfuse`` and is often faster. On Mac only the FUSE option is available: - First install `macFUSE `_, eg via ``brew install --cask macfuse``. - Then install ``squashfuse``, ideally from `source `_. Python Example -------------- Create an environment: .. code-block:: bash $ conda create -y -n example python=3.9 numpy pandas scikit-learn Pack the environment into SquashFS: .. code-block:: bash $ conda pack -n example --format squashfs --n-threads 4 Create a directory to mount to: .. code-block:: bash $ mkdir env_mountpoint Option 1 (Linux + MacOS): Mount the environment using squashfuse: .. code-block:: bash $ squashfuse example.squashfs env_mountpoint Option 2 (Linux): Mount the environment using ``mount``: .. code-block:: bash $ sudo mount -t squashfs example.squashfs env_mountpoint Compression options ------------------- Compression can be specified through ``--compress-level``. Default is level 4, which will use ``zstd`` compression. When selecting a compression option for packing, keep in mind the kernel or ``squashfuse`` version on the target system. For older systems, make sure that SquashFS or ``squashfuse`` support ``zstd`` compression (Linux kernel version ``>=4.14`` or ``squashfuse >= 0.1.101``). If ``zstd`` isn't supported on the target, you can always compress with ``xz`` instead. - 0: no compression - 1-8: ``zstd`` with increasing compression level - 9: ``xz`` Making the unpacked environment writeable ----------------------------------------- SquashFS is a read-only filesystem. Sometimes the unpacked environment needs to be writeable on the target machine, for example to install more packages. A good way to do this is to use `Union mounting `_ to add a writeable layer on top of the read-only SquashFS. On Linux the most used option is `OverlayFS `_. To set this up, we create three layers: 1. The SquashFS-packed conda env as a read-only lower layer 2. A writeable working directory, necessary for OverlayFS 3. A writeable upper directory, where all new and changed files will go .. code-block:: bash $ # 1. Create read-only lower layer, consisting of squashFS-packed conda env $ mkdir squashFS_mountpoint $ sudo mount -t squashfs example.squashfs squashFS_mountpoint $ # 2. Create workdir & 3. Create upperdir $ mkdir workdir upperdir Now we combine them into a single directory ``writeable_env``, which will contain our environment but which will be writeable. .. code-block:: bash $ mkdir writeable_env $ sudo mount -t overlay overlay \ -o lowerdir=squashFS_mountpoint,upperdir=upperdir,workdir=workdir writeable_env Any files created in the ``writeable_env`` directory will also show up in ``upperdir``. After unmounting, delete ``upperdir`` and ``workdir`` and all changes made to the environment will be gone.