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/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..b246933 --- /dev/null +++ b/wsl-oobe.sh @@ -0,0 +1,52 @@ +#!/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 + +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 + 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 + +# Create the user +/usr/sbin/useradd -m -G wheel --uid $DEFAULT_USER_ID "$username" + +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 + +# 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'" diff --git a/wsl-setup b/wsl-setup new file mode 100755 index 0000000..4722334 --- /dev/null +++ b/wsl-setup @@ -0,0 +1,86 @@ +#!/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 "ERROR: Name is not provided" + echo + usage + exit 2 + fi +;; +--icon | -i ) + if ! [ "${2}" == "" ] ; then + ICON_PATH="${2}" + shift + else + echo "ERROR: Icon full path is not provided" + echo + usage + exit 2 + fi +;; +* ) + usage + exit 2 +;; +esac +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..23ba7b5 --- /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..f4f8495 --- /dev/null +++ b/wsl-setup.spec @@ -0,0 +1,79 @@ +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 + + +%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 %{_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