From 5afaf63d99184801fe5688c05c5aba6a6bb2041d Mon Sep 17 00:00:00 2001 From: Simon de Vlieger Date: Wed, 28 May 2025 12:01:25 +0200 Subject: [PATCH 01/12] oobe: exit early for cloud-init WSL supports `cloud-init` for provisioning. In some cases (RHEL) this is enabled. If `wsl-setup` is used on RHEL then there's a TOCTOU between the check for "no user exists" and the "create user" part as `cloud-init` creates the user during the prompt. Let's exit early and assume everything is handled by `cloud-init` *if* it is enabled. Signed-off-by: Simon de Vlieger --- wsl-oobe.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/wsl-oobe.sh b/wsl-oobe.sh index ace2e51..240dde6 100644 --- a/wsl-oobe.sh +++ b/wsl-oobe.sh @@ -2,7 +2,8 @@ # The Fedora WSL out of box experience script. # -# This command runs the first time the user opens an interactive shell. +# This command runs the first time the user opens an interactive shell if +# `cloud-init` is not enabled. # # A non-zero exit code indicates to WSL that setup failed. @@ -10,6 +11,10 @@ set -ueo pipefail DEFAULT_USER_ID=1000 +if systemctl is-enabled cloud-init.service > /dev/null ; then + exit 0 +fi + echo 'Please create a default user account. The username does not need to match your Windows username.' echo 'For more information visit: https://aka.ms/wslusers' From 3ee41192ed2efe6a791947f0c2f8b7d6d69647b7 Mon Sep 17 00:00:00 2001 From: Simon de Vlieger Date: Thu, 5 Jun 2025 16:45:11 +0200 Subject: [PATCH 02/12] oobe: message for enabled cloud-init Show a message when cloud-init is enabled so users know what is going on. Signed-off-by: Simon de Vlieger --- wsl-oobe.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/wsl-oobe.sh b/wsl-oobe.sh index 240dde6..b55e831 100644 --- a/wsl-oobe.sh +++ b/wsl-oobe.sh @@ -12,6 +12,7 @@ set -ueo pipefail DEFAULT_USER_ID=1000 if systemctl is-enabled cloud-init.service > /dev/null ; then + echo 'cloud-init is enabled, skipping user account creation' exit 0 fi From fc30a377e89fc19665dc0180f74162bee90789e1 Mon Sep 17 00:00:00 2001 From: Simon de Vlieger Date: Wed, 18 Jun 2025 20:26:14 +0200 Subject: [PATCH 03/12] oobe: wait for cloud-init to finish Let's wait for `cloud-init` to finish before we exit the OOBE; this ensures that any potential user has been created. In the future we might want to always continue with our OOBE, in those cases that `cloud-init` didn't create a user we can then continue with the prompt(s). Signed-off-by: Simon de Vlieger --- wsl-oobe.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wsl-oobe.sh b/wsl-oobe.sh index b55e831..b246933 100644 --- a/wsl-oobe.sh +++ b/wsl-oobe.sh @@ -12,7 +12,8 @@ set -ueo pipefail DEFAULT_USER_ID=1000 if systemctl is-enabled cloud-init.service > /dev/null ; then - echo 'cloud-init is enabled, skipping user account creation' + echo 'cloud-init is enabled, skipping user account creation. Waiting for cloud-init to finish.' + cloud-init status --wait > /dev/null 2>&1 exit 0 fi From 99ab88e36171f10035c6733015fa824d0dab0125 Mon Sep 17 00:00:00 2001 From: Jeremy Cline Date: Tue, 1 Jul 2025 10:43:55 -0400 Subject: [PATCH 04/12] Add Requires for utilities used in the OOBE script The OOBE script uses adduser from the shadow-utils package and systemctl to inspect service state, so we should require those be installed. This is particularly important for users building custom WSL images since we explicitly list both those packages in our Kiwi config. Suggested-by: Simon de Vlieger Signed-off-by: Jeremy Cline --- wsl-setup.spec | 3 +++ 1 file changed, 3 insertions(+) diff --git a/wsl-setup.spec b/wsl-setup.spec index f4f8495..6e895dd 100644 --- a/wsl-setup.spec +++ b/wsl-setup.spec @@ -20,6 +20,9 @@ BuildRequires: systemd-rpm-macros # Needed for the distribution icon Requires: system-logos +# Utilities used by the OOBE script +Requires: shadow-utils +Requires: systemd %description Provides WSL specific configuration files and first-time setup script. From ef26ebb240bf6135daf73e525212e09733e6fc5c Mon Sep 17 00:00:00 2001 From: Jeremy Cline Date: Mon, 30 Jun 2025 15:37:32 -0400 Subject: [PATCH 05/12] oobe: don't append the user section to /etc/wsl.conf Doing this apparently[0] breaks using `wsl --manage --set-default-user` (in my test, wsl says it completed successfully, but actually doesn't do anything at all). Since we set the default UID in wsl-distribution.conf, the default default user will be UID 1000, which we expect to create anyway. While it's nice to support old versions of WSL, I think it's also reasonable to require users to update to ensure things work. For example, most things in Fedora expect cgroups v2, but WSL only removed cgroups v1 in 2.5. If users report an issue and note they're not using the latest WSL stable release I'm just going to tell them to reproduce it on the latest, and if they can't I'm not going to spend any time trying to make it work. [0] https://github.com/microsoft/WSL/pull/13094#issuecomment-2971990351 Signed-off-by: Jeremy Cline --- wsl-oobe.sh | 8 -------- 1 file changed, 8 deletions(-) diff --git a/wsl-oobe.sh b/wsl-oobe.sh index b246933..780dadd 100644 --- a/wsl-oobe.sh +++ b/wsl-oobe.sh @@ -40,13 +40,5 @@ cat > /etc/sudoers.d/wsluser << EOF $username ALL=(ALL) NOPASSWD: ALL EOF -# Set the default user; necessary when this script is manually run in versions -# of WSL prior to 2.4. -cat >> /etc/wsl.conf << EOF - -[user] -default = "$username" -EOF - echo 'Your user has been created, is included in the wheel group, and can use sudo without a password.' echo "To set a password for your user, run 'sudo passwd $username'" From b879d40631220f3686744666fe332e4c8d9fc62f Mon Sep 17 00:00:00 2001 From: Troy Dawson Date: Mon, 7 Jul 2025 13:39:46 -0700 Subject: [PATCH 06/12] Fix script arguments section Signed-off-by: Troy Dawson --- wsl-setup | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/wsl-setup b/wsl-setup index 4722334..41bb0b0 100755 --- a/wsl-setup +++ b/wsl-setup @@ -54,6 +54,7 @@ case $key in DEFAULT_NAME="${2}" shift else + echo echo "ERROR: Name is not provided" echo usage @@ -65,6 +66,7 @@ case $key in ICON_PATH="${2}" shift else + echo echo "ERROR: Icon full path is not provided" echo usage @@ -72,10 +74,14 @@ case $key in fi ;; * ) + echo + echo "ERROR BAD OPTION: $key" + echo usage exit 2 ;; esac +shift done ############### From bbafa4924c5dabb29fa30a43b3830c2bdaceb897 Mon Sep 17 00:00:00 2001 From: Simon de Vlieger Date: Fri, 11 Jul 2025 11:36:29 +0200 Subject: [PATCH 07/12] oobe: ignore cloud-init warnings `cloud-init` features multiple different non-zero exit codes [1]. Most importantly it can return `2` for recoverable errors. This happens commonly in RHEL land where WSL images currently contain, and enable `cloud-init`. When the user does not provide a WSL data source (configures their host) then the fallback data source of `None` is used by `cloud-init`. This emits a warning and thus `cloud-init` returns a non-zero exit status. Let's ignore any exit code that isn't `1` (critical). If there *was* a critical error we now also show the error message contained in `cloud-init status`. [1]: https://docs.cloud-init.io/en/latest/explanation/failure_states.html#cloud-init-error-codes Signed-off-by: Simon de Vlieger --- wsl-oobe.sh | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/wsl-oobe.sh b/wsl-oobe.sh index 780dadd..3fbc38f 100644 --- a/wsl-oobe.sh +++ b/wsl-oobe.sh @@ -11,9 +11,27 @@ set -ueo pipefail DEFAULT_USER_ID=1000 +# When `cloud-init` is enabled it might take care of user creation and other bits, depending on its +# configuration contained within the WSL image; or the WSL configuration as provided by the host. if systemctl is-enabled cloud-init.service > /dev/null ; then echo 'cloud-init is enabled, skipping user account creation. Waiting for cloud-init to finish.' - cloud-init status --wait > /dev/null 2>&1 + + # We need to run cloud-init in a sub-shell that disables errexit so we can inspect its error code + # Without the script exiting. + (set +e cloud-init status --wait > /dev/null 2>&1) + + cloud_status=$? + + # We only exit unsuccesfully on a cloud-init exit status of 1. This means an unrecoverable error, + # and the system might not be usable. Any other exit status (0 for success, or 2 for warning) can + # be ignored and happens commonly, for example when there is a default configuration but the fallback + # data source was used. + if [ "${cloud_status}" -eq 1 ]; then + echo 'cloud-init failed unrecoverably. Failed to provision system.' + cloud-init status --long + exit 1 + fi + exit 0 fi From c6758f12f19a5fc974990fde97b7b1e70884267e Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 25 Jul 2025 20:33:43 +0000 Subject: [PATCH 08/12] Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild From c937ddd38f1a928c8a1d41712f05d09fceb09e89 Mon Sep 17 00:00:00 2001 From: Li Tian Date: Tue, 23 Sep 2025 12:30:51 +0800 Subject: [PATCH 09/12] tmpfiles: not forcefully create symlink /tmp/.X11-unix In RHEL/CentOS, the X11 socket is created in /tmp fine. Do not forcefully create it which cause an error during installation using dnf/yum. Signed-off-by: Li Tian --- wsl-setup-tmpfiles.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wsl-setup-tmpfiles.conf b/wsl-setup-tmpfiles.conf index 23ba7b5..a9c3d1f 100644 --- a/wsl-setup-tmpfiles.conf +++ b/wsl-setup-tmpfiles.conf @@ -1 +1 @@ -L+ /tmp/.X11-unix - - - - /mnt/wslg/.X11-unix +L /tmp/.X11-unix - - - - /mnt/wslg/.X11-unix From 9a77cca64b20881593574f8e054eb2dc5fdb84b4 Mon Sep 17 00:00:00 2001 From: Li Tian Date: Mon, 22 Sep 2025 13:08:56 +0800 Subject: [PATCH 10/12] wsl-setup: fix --help|-h option error prompt --help|-h ought not to fall into error prompt. Signed-off-by: Li Tian --- wsl-setup | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/wsl-setup b/wsl-setup index 41bb0b0..698ca18 100755 --- a/wsl-setup +++ b/wsl-setup @@ -73,6 +73,10 @@ case $key in exit 2 fi ;; +--help | -h ) + usage + exit 0 +;; * ) echo echo "ERROR BAD OPTION: $key" From ce747b8b8e9760853a8608e6e9a1b137040a4491 Mon Sep 17 00:00:00 2001 From: Li Tian Date: Mon, 22 Sep 2025 13:13:17 +0800 Subject: [PATCH 11/12] wsl-oobe.sh: Ask for re-input of username when error Ask for re-input when username either is invalid or exists. Signed-off-by: Li Tian --- wsl-oobe.sh | 46 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/wsl-oobe.sh b/wsl-oobe.sh index 3fbc38f..5cb4a69 100644 --- a/wsl-oobe.sh +++ b/wsl-oobe.sh @@ -11,6 +11,42 @@ set -ueo pipefail DEFAULT_USER_ID=1000 +function create_user() { + local rc=0 + + while true; do + read -r -p "Create a default Unix user account: " username + + # Create the user. + rc=$( + set +e + /usr/sbin/useradd -m -G wheel --uid "$DEFAULT_USER_ID" "$username" > /dev/null + echo $? + ) + + case $rc in + # 3: invalid argument to option + # 19: Bad login name (since Fedora 42) + 3 | 19) + echo "Invalid username. A valid username must start with a letter or underscore, and can contain letters, digits, underscores, dots, dashes and a dollar sign at the end." + continue + ;; + # 9: username or group name already in use + 9) + echo "User \"$username\" already exists" + continue + ;; + 0) + break + ;; + *) + echo "Unexpected error code from useradd: $rc" + break + ;; + esac + done +} + # When `cloud-init` is enabled it might take care of user creation and other bits, depending on its # configuration contained within the WSL image; or the WSL configuration as provided by the host. if systemctl is-enabled cloud-init.service > /dev/null ; then @@ -35,19 +71,15 @@ if systemctl is-enabled cloud-init.service > /dev/null ; then exit 0 fi -echo 'Please create a default user account. The username does not need to match your Windows username.' -echo 'For more information visit: https://aka.ms/wslusers' - if getent passwd $DEFAULT_USER_ID > /dev/null ; then echo 'User account already exists, skipping creation' exit 0 fi -# Prompt from the username -read -r -p 'Enter new UNIX username: ' username +echo 'Please create a default user account. The username does not need to match your Windows username.' +echo 'For more information visit: https://aka.ms/wslusers' -# Create the user -/usr/sbin/useradd -m -G wheel --uid $DEFAULT_USER_ID "$username" +create_user cat > /etc/sudoers.d/wsluser << EOF # Ensure the WSL initial user can use sudo without a password. From 8fa8ffc5e5a266018239a449ac78abca750d11f8 Mon Sep 17 00:00:00 2001 From: Troy Dawson Date: Tue, 21 Oct 2025 11:58:00 -0700 Subject: [PATCH 12/12] Fix ghost file permissions Signed-off-by: Troy Dawson --- wsl-setup.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wsl-setup.spec b/wsl-setup.spec index 6e895dd..4c637a0 100644 --- a/wsl-setup.spec +++ b/wsl-setup.spec @@ -67,7 +67,7 @@ install -Dpm0644 %{SOURCE5} %{buildroot}%{_unitdir}/systemd-firstboot.service.d/ %files %{_bindir}/wsl-setup %config(noreplace) %{_sysconfdir}/wsl.conf -%ghost %{_prefix}/lib/wsl-distribution.conf +%ghost %attr(644, root, root) %{_prefix}/lib/wsl-distribution.conf %{_sysconfdir}/wsl-distribution.conf %dir %{_datarootdir}/wsl-setup/ %{_datarootdir}/wsl-setup/wsl-distribution.conf.template