As you already know, Windows 10 Developer mode bring one feature called Windows Subsystem for Linux, or popular as ‘Bash on Ubuntu on Windows’. This great feature bring linux-based terminal apps and experience to Windows desktop.

Todays, Microsoft only in partnership with Canonical to bring Bash on Ubuntu environment in Windows 10, none other distro can be installed on thoose technology. Until now, a developer and hacker, Roland Bogosi, create a open-source project called WSL Distribution Switcher on Github.

WSL Distribution Switcher is easy download and install new Linux distributions under Windows Subsystem for Linux and seamlessly switch between them. Of course, there is no hard and fast reason why you should switch from Ubuntu to other distribution. But, if you curious person and take linux distro choice as serious gear picking, you should use and participate to develop this project.

More Technical

The rootfs archives used in WSL Distribution Switcher are currently downloaded from Docker Hub’s official images’ repositories (“source”) or published image layers (“prebuilt”).

So, the scripts provided here are written in Python 3, and they need to be run from Windows, NOT from WSL. You can download a Python 3 installer from their official website, or you can use the one bundled with Cygwin. Since WSL is stored in %LocalAppData% for each user, you don’t need admin rights in order to use any of the scripts.

To begin, clone the repository or download a copy of it from its Github repository here.

To install new distribution under Windows Subsystem for Linux you can use get-source.py script. Simply by run the script with distribution tag. For example, to get the rootfs tarball for Debian Sid, just run get-source.py debian:sid. If you don’t specify a tag, latest will be used, which is generally the stable edition of the distribution.

$ python get-source.py debian:sid
[*] Fetching official-images info for debian:sid...
[*] Fetching Dockerfile from repo tianon/docker-brew-debian/.../sid...
[*] Downloading archive https://raw.githubusercontent.com/.../sid/rootfs.tar.xz...
[*] Rootfs archive for debian:sid saved to rootfs_debian_sid.tar.xz.

Now, WSL Distribution only available for this distribution tag:

  • debian – 8.5, 8, jessie, latest | jessie-backports | oldstable | oldstable-backports | sid | stable | stable-backports | stretch | testing | unstable | 7.11, 7, wheezy | wheezy-backports | rc-buggy | experimental
  • ubuntu – 12.04.5, 12.04, precise-20160707, precise | 14.04.5, 14.04, trusty-20160802, trusty | 16.04, xenial-20160809, xenial, latest | 16.10, yakkety-20160806.1, yakkety, devel
  • fedora – latest, 24 | 23 | 22 | 21 | rawhide | 20, heisenbug
  • centos – latest, centos7, 7 | centos6, 6 | centos5, 5 | centos7.2.1511, 7.2.1511 | centos7.1.1503, 7.1.1503 | centos7.0.1406, 7.0.1406 | centos6.8, 6.8 | centos6.7, 6.7 | centos6.6, 6.6 | centos5.11, 5.11
  • opensuse – 42.1, leap, latest | 13.2, harlequin | tumbleweed
  • mageia – latest, 5
  • oraclelinux – latest, 7, 7.2 | 7.1 | 7.0 | 6, 6.8 | 6.7 | 6.6 | 5, 5.11
  • alpine – 3.1 | 3.2 | 3.3 | 3.4, latest | edge
  • crux – latest, 3.1
  • clearlinux – latest, base

Installing new rootfs

The install.py script is responsible for installing the tarballs as new rootfs.

The first argument of the script is either the a) name of the file or the b) same image:tag notation used in the get.py script: install.py image[:tag] | tarball | squashfs. You can install tarballs from sources other than the Docker Hub, however, they’re not guaranteed to work.

The specified file can be a .tar* archive, or a SquashFS image with .sfs or .squashfs extension. In order to process SquashFS images, the PySquashfsImage Python module nees to be installed, which you can do with pip3 install PySquashfsImage.

To install the freshly downloaded rootfs_debian_sid.tar.xz archive, run install.py debian:sid or install.py rootfs_debian_sid.tar.xz.

$ python install.py debian:sid
[*] Probing the Linux subsystem...
[*] Default user is RoliSoft at /home/RoliSoft.
[*] Switching default user to root...
[*] Reading /etc/{passwd,shadow,group,gshadow} entries for root and RoliSoft...
[*] Removing leftover rootfs-temp...
[*] Copying rootfs_debian_sid.tar.xz to /root/rootfs-temp...
[*] Beginning extraction...
[*] Waiting for the Linux subsystem to exit...
[*] Backing current rootfs to rootfs_ubuntu_trusty...
[*] Switching to new rootfs...
[*] Writing entries of root and RoliSoft to /etc/{passwd,shadow,group,gshadow}...
[*] Switching default user back to RoliSoft...

This operation extracts the tarball into your home directory in WSL, then replaces the current rootfs with the new one.

Earlier version of this script spawned a new WSL shell, and ran the extraction command under the subsystem. For newer versions, the bundled ntfsea library provides functionality to write the NTFS extended attributes required for VoIFS, and as such, extraction now happens without the involvement of WSL. This means that broken rootfs installations can now be repaired to some extent, since the WSL does not have to be able to start beforehand.

Running bash after installation should launch the new distribution:

> bash
$ cat /etc/debian_version
stretch/sid

Switching between distributions

The switch.py script is responsible for switching between the installed distributions.

All installed distributions are labelled through a .switch-label file in the root directory. This is created from Windows, so it is not visible from within WSL and is only used by the switcher script.

When switching between distributions, the rootfs folder is renamed: the old one will get the value from the .switch-label file appended to it, e.g. rootfs_debian_sid, while the new one will be renamed from its rootfs_ubuntu_trusty name to rootfs in order to become the active one.

The /home, /root and similar directories are stored separately, and as such switching between distributions can be seamless, as your personal and dotfiles will persist and will never be touched during any operation.

The default installation is Ubuntu Trusty. Any rootfs directory with no switch label inside will automatically be labelled ubuntu:trusty, so this is the argument you’ll have to specify if you want to go back to the original installation.

When the script is run without any arguments, the list of installed distributions will be returned:

$ python switch.py
usage: ./switch.py image[:tag]

The following distributions are currently installed:

  • debian:sid*
  • fedora:rawhide
  • ubuntu:trusty

To switch back to the default distribution, specify ubuntu:trusty as the argument. To switch between the distributions, just run the script with the image:tag you want to switch to:

$ python switch.py fedora:rawhide
[*] Probing the Linux subsystem...
[*] Moving current rootfs to rootfs_ubuntu_trusty...
[*] Moving desired rootfs_fedora_rawhide to rootfs...

$ bash -c 'dnf --version'
1.1.9
Installed: dnf-0:1.1.9-6.fc26.noarch at 2016-08-12 08:30
Built : Fedora Project at 2016-08-09 16:53
...

$ python switch.py debian:sid
[*] Probing the Linux subsystem...
[*] Moving current rootfs to rootfs_fedora_rawhide...
[*] Moving desired rootfs_debian_sid to rootfs...

$ bash -c 'apt-get -v'
apt 1.3~pre2 (amd64)
Supported modules:
*Ver: Standard .deb
...

As mentioned before, switching is just 2 directory rename operations. However, WSL cannot be running while this is happening.

Source: Github