diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..570ff3f --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +Copyright 2025 Fedora Project Authors. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..63f5317 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# wsl-setup + +The wsl-setup package diff --git a/dead.package b/dead.package deleted file mode 100644 index bfe1766..0000000 --- a/dead.package +++ /dev/null @@ -1 +0,0 @@ -Added to RHEL 9.7 rhbz#2374941 diff --git a/firstboot-override.conf b/firstboot-override.conf new file mode 100644 index 0000000..c6fab5d --- /dev/null +++ b/firstboot-override.conf @@ -0,0 +1,2 @@ +[Unit] +ConditionVirtualization=!wsl diff --git a/sources b/sources new file mode 100644 index 0000000..e69de29 diff --git a/wsl-distribution.conf b/wsl-distribution.conf new file mode 100644 index 0000000..3c8e1e5 --- /dev/null +++ b/wsl-distribution.conf @@ -0,0 +1,23 @@ +# The /etc/wsl-distribution.conf configuration file. +# +# This is not intended to be edited by users; it is how WSL discovers +# distribution defaults. +# +# Available configuration options are documented at +# https://learn.microsoft.com/en-us/windows/wsl/build-custom-distro + +[oobe] +# Command run the first time the user opens an interactive shell. +# If the command returns non-zero, it is considered unsuccessful and the +# user won't be able to open a shell. +command = /usr/libexec/wsl/oobe.sh +# Default UID for user the distribution starts with. +defaultUid = 1000 +# Default name the distribution is registered under. +# This is used when the user double-clicks to install, or uses +# wsl --install --from-file ./Fedora.wsl +defaultName = DEFAULT_NAME + +[shortcut] +enabled = true +icon = DEFAULT_ICON_FULL_PATH diff --git a/wsl-oobe.sh b/wsl-oobe.sh new file mode 100644 index 0000000..5cb4a69 --- /dev/null +++ b/wsl-oobe.sh @@ -0,0 +1,94 @@ +#!/bin/bash + +# The Fedora WSL out of box experience script. +# +# 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. + +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 + echo 'cloud-init is enabled, skipping user account creation. Waiting for cloud-init to finish.' + + # 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 + +if getent passwd $DEFAULT_USER_ID > /dev/null ; then + echo 'User account already exists, skipping creation' + 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' + +create_user + +cat > /etc/sudoers.d/wsluser << EOF +# Ensure the WSL initial user can use sudo without a password. +# +# Since the user is in the wheel group, this file can be removed +# if you wish to require a password for sudo. Be sure to set a +# user password before doing so with 'sudo passwd $username'! +$username ALL=(ALL) NOPASSWD: ALL +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'" diff --git a/wsl-setup b/wsl-setup new file mode 100755 index 0000000..698ca18 --- /dev/null +++ b/wsl-setup @@ -0,0 +1,96 @@ +#!/usr/bin/bash +# +# Setup the environment for the new WSL configuration +# +# Copyright (C) 2025 +# SPDX-License-Identifier: MIT +# +# Authors: +# Troy Dawson +# + +############### +# Variables +############### +DISTRIBUTION_TEMPLATE_FILE="/usr/share/wsl-setup/wsl-distribution.conf.template" +DISTRIBUTION_CONF_FILE="/usr/lib/wsl-distribution.conf" +DISTRIBUTION_CONF_LINK="/etc/wsl-distribution.conf" +. /etc/os-release +DEFAULT_NAME="${NAME// /}-${VERSION_ID%.*}" +ICON_PATH="/usr/share/pixmaps/fedora-logo.ico" + +############### +# Show help +############### +usage() { + echo "Usage `basename $0` " >&2 + echo >&2 + echo "Setup the environment for the new WSL configuration" >&2 + echo >&2 + echo "Options:" >&2 + echo " --name, -n" >&2 + echo " Set the distro name" >&2 + echo " Default: ${DEFAULT_NAME}" >&2 + echo " --icon, -i" >&2 + echo " Full pathname to the icon" >&2 + echo " Default: ${ICON_PATH}" >&2 + echo " --help, -h" >&2 + echo " Show this options menu" >&2 + echo >&2 + popd &>/dev/null + exit 1 +} + + +############### +# Get our arguments +############### +while [[ "$#" -ge 1 ]] +do +key="$1" +case $key in +--name | -n ) + if ! [ "${2}" == "" ] ; then + DEFAULT_NAME="${2}" + shift + else + echo + echo "ERROR: Name is not provided" + echo + usage + exit 2 + fi +;; +--icon | -i ) + if ! [ "${2}" == "" ] ; then + ICON_PATH="${2}" + shift + else + echo + echo "ERROR: Icon full path is not provided" + echo + usage + exit 2 + fi +;; +--help | -h ) + usage + exit 0 +;; +* ) + echo + echo "ERROR BAD OPTION: $key" + echo + usage + exit 2 +;; +esac +shift +done + +############### +# Do the work +############### + +cp -f ${DISTRIBUTION_TEMPLATE_FILE} ${DISTRIBUTION_CONF_FILE} +sed -i -e "s|DEFAULT_NAME|${DEFAULT_NAME}|" -e "s|DEFAULT_ICON_FULL_PATH|${ICON_PATH}|" ${DISTRIBUTION_CONF_FILE} diff --git a/wsl-setup-tmpfiles.conf b/wsl-setup-tmpfiles.conf new file mode 100644 index 0000000..a9c3d1f --- /dev/null +++ b/wsl-setup-tmpfiles.conf @@ -0,0 +1 @@ +L /tmp/.X11-unix - - - - /mnt/wslg/.X11-unix diff --git a/wsl-setup-user-tmpfiles.conf b/wsl-setup-user-tmpfiles.conf new file mode 100644 index 0000000..6a155a8 --- /dev/null +++ b/wsl-setup-user-tmpfiles.conf @@ -0,0 +1,3 @@ +L+ /run/user/%U/wayland-0.lock - - - - /mnt/wslg/runtime-dir/wayland-0.lock +L+ /run/user/%U/wayland-0 - - - - /mnt/wslg/runtime-dir/wayland-0 +L+ /run/user/%U/pulse - - - - /mnt/wslg/runtime-dir/pulse diff --git a/wsl-setup.spec b/wsl-setup.spec new file mode 100644 index 0000000..4c637a0 --- /dev/null +++ b/wsl-setup.spec @@ -0,0 +1,82 @@ +Name: wsl-setup +Version: 1.0.1 +Release: %autorelease +Summary: Windows Subsystem for Linux setup script and configuration +License: MIT +URL: https://src.fedoraproject.org/rpms/wsl-setup +BuildArch: noarch + +Source1: LICENSE +Source2: wsl.conf +Source3: wsl-distribution.conf +Source4: wsl-oobe.sh +Source5: firstboot-override.conf +Source6: wsl-setup-tmpfiles.conf +Source7: wsl-setup-user-tmpfiles.conf +Source8: wsl-setup + +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. + + +%prep + + +%build + + +%install +install -pm 0644 %{SOURCE1} LICENSE +install -Dpm0644 -t %{buildroot}%{_sysconfdir}/ %{SOURCE2} +install -Dpm0644 -T %{SOURCE3} %{buildroot}%{_datarootdir}/wsl-setup/wsl-distribution.conf.template +install -Dpm0755 -T %{SOURCE4} %{buildroot}%{_libexecdir}/wsl/oobe.sh +install -Dpm0755 -T %{SOURCE8} %{buildroot}%{_bindir}/wsl-setup +ln -s ..%{_prefix}/lib/wsl-distribution.conf %{buildroot}%{_sysconfdir}/wsl-distribution.conf + +# WSL provides a socket for x11, but we need to ensure its linked to in /tmp. +# The official recommendation is to disable tmpfiles entirely, but it would be +# nice to work with it, instead. +# https://learn.microsoft.com/en-us/windows/wsl/build-custom-distro#systemd-recommendations +install -Dpm0644 %{SOURCE6} %{buildroot}%{_tmpfilesdir}/%{name}.conf + +# WSL provides a Wayland and PulseAudio socket as well, which are expected to be in +# the user's runtime directory. This configuration sets up the links for each user. +install -Dpm0644 %{SOURCE7} %{buildroot}%{_user_tmpfilesdir}/%{name}.conf + +# Currently systemd-firstboot hangs forever attempting to acquire the console; this is +# problematic since many other services wait for it to complete before starting, including +# things like the system D-Bus. Configure it to not run in WSL (a preset didn't seem to work) +# until we can see about adjusting either WSL or systemd to make it behave. +install -Dpm0644 %{SOURCE5} %{buildroot}%{_unitdir}/systemd-firstboot.service.d/override.conf + + +%post +# generate the "auto" naming, using the defaults +%{_bindir}/wsl-setup + + +%files +%{_bindir}/wsl-setup +%config(noreplace) %{_sysconfdir}/wsl.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 +%{_libexecdir}/wsl/oobe.sh +%{_tmpfilesdir}/%{name}.conf +%{_user_tmpfilesdir}/%{name}.conf +%{_unitdir}/systemd-firstboot.service.d/override.conf +%license LICENSE + + +%changelog +%autochangelog diff --git a/wsl.conf b/wsl.conf new file mode 100644 index 0000000..1a92e7c --- /dev/null +++ b/wsl.conf @@ -0,0 +1,4 @@ +# Refer to https://learn.microsoft.com/en-us/windows/wsl/wsl-config#wslconf +# for the full set of configuration options. +[boot] +systemd=true