@@ -9,21 +9,31 @@ def initialize(machine)
99 @config = machine . provider_config
1010 end
1111
12+ # Get the distribution name, preferring machine.id if it exists
13+ def distribution_name
14+ @machine . id || @config . distribution_name
15+ end
16+
1217 # Get the current state of the WSL2 distribution
1318 def state
14- # Check if distribution exists by trying to get its state
15- result = Vagrant ::Util ::Subprocess . execute ( "wsl" , "--distribution" , @config . distribution_name , "--exec" , "echo" )
16-
17- case result . exit_code
18- when 0
19- # Distribution exists and is accessible, check if running
20- running_result = Vagrant ::Util ::Subprocess . execute ( "wsl" , "--distribution" , @config . distribution_name , "--exec" , "true" )
21- return running_result . exit_code == 0 ? :running : :stopped
22- when 1 , 4294967295
23- # Distribution doesn't exist or WSL error
24- :not_created
19+ # Return :not_created if we don't have a distribution name yet
20+ return :not_created unless distribution_name
21+
22+ # Use wsl --list --verbose to check state without waking up the distribution
23+ result = execute_safe ( "wsl" , "--list" , "--verbose" )
24+ return :not_created unless result
25+
26+ distributions = parse_wsl_list_output ( result . stdout )
27+ distro = distributions . find { |d | d [ :name ] == distribution_name }
28+
29+ return :not_created unless distro
30+
31+ case distro [ :state ]
32+ when "Running"
33+ :running
34+ when "Stopped"
35+ :stopped
2536 else
26- # Unknown error state
2737 :unknown
2838 end
2939 rescue
@@ -37,25 +47,26 @@ def create(box_path)
3747 FileUtils . mkdir_p ( dist_dir ) unless File . exist? ( dist_dir )
3848
3949 # Import the distribution from a tar.gz file
40- execute ( "wsl" , "--import" , @config . distribution_name ,
50+ execute ( "wsl" , "--import" , distribution_name ,
4151 dist_dir , box_path , "--version" , @config . version . to_s )
4252 end
4353
4454 # Start the WSL2 distribution
45- def start
46- @machine . ui . info "Starting WSL2 distribution: #{ @config . distribution_name } "
47- execute ( "wsl" , "--distribution" , @config . distribution_name , "--exec" , "true" )
55+ # @param silent [Boolean] If true, suppress UI output
56+ def start ( silent : false )
57+ @machine . ui . info "Starting WSL2 distribution: #{ distribution_name } " unless silent
58+ execute ( "wsl" , "--distribution" , distribution_name , "--exec" , "true" )
4859 end
4960
5061 # Stop the WSL2 distribution
5162 def halt
52- @machine . ui . info "Stopping WSL2 distribution: #{ @config . distribution_name } "
53- execute ( "wsl" , "--terminate" , @config . distribution_name )
63+ @machine . ui . info "Stopping WSL2 distribution: #{ distribution_name } "
64+ execute ( "wsl" , "--terminate" , distribution_name )
5465 end
5566
5667 # Destroy the WSL2 distribution
5768 def destroy
58- execute ( "wsl" , "--unregister" , @config . distribution_name )
69+ execute ( "wsl" , "--unregister" , distribution_name )
5970
6071 # Wait a moment for WSL to release file handles
6172 sleep 1
@@ -82,7 +93,7 @@ def destroy
8293
8394 # Execute a command in the WSL2 distribution
8495 def execute_in_wsl ( *args )
85- execute ( "wsl" , "--distribution" , @config . distribution_name , *args )
96+ execute ( "wsl" , "--distribution" , distribution_name , *args )
8697 end
8798
8899 # Public wrapper for execute method (for use by actions)
@@ -139,7 +150,7 @@ def save_snapshot(snapshot_name)
139150
140151 # Export the current distribution to a tar file
141152 @machine . ui . info "Saving snapshot: #{ snapshot_name } "
142- execute ( "wsl" , "--export" , @config . distribution_name , snapshot_file )
153+ execute ( "wsl" , "--export" , distribution_name , snapshot_file )
143154
144155 @machine . ui . success "Snapshot saved: #{ snapshot_name } "
145156 end
@@ -156,13 +167,13 @@ def restore_snapshot(snapshot_name)
156167
157168 # First, unregister the current distribution
158169 halt if state == :running
159- execute ( "wsl" , "--unregister" , @config . distribution_name )
170+ execute ( "wsl" , "--unregister" , distribution_name )
160171
161172 # Import the snapshot as the distribution
162173 dist_dir = distribution_path
163174 FileUtils . mkdir_p ( dist_dir ) unless File . exist? ( dist_dir )
164175
165- execute ( "wsl" , "--import" , @config . distribution_name ,
176+ execute ( "wsl" , "--import" , distribution_name ,
166177 dist_dir , snapshot_file , "--version" , @config . version . to_s )
167178
168179 @machine . ui . success "Snapshot restored: #{ snapshot_name } "
@@ -267,7 +278,7 @@ def data_disk_already_mounted?(expected_disk_count)
267278 # Count block devices that could be data disks (sde and later)
268279 # Use wsl -d to run command inside the distribution
269280 result = Vagrant ::Util ::Subprocess . execute (
270- "wsl" , "-d" , @config . distribution_name , "--" , "lsblk" , "-nd" , "-o" , "NAME"
281+ "wsl" , "-d" , distribution_name , "--" , "lsblk" , "-nd" , "-o" , "NAME"
271282 )
272283 return false if result . exit_code != 0
273284
@@ -424,6 +435,39 @@ def execute_safe(*args)
424435 def distribution_path
425436 @machine . data_dir . join ( "wsl2_distribution" ) . to_s
426437 end
438+
439+ # Parse WSL list output to extract distribution information
440+ def parse_wsl_list_output ( output )
441+ distributions = [ ]
442+
443+ # Handle UTF-16LE encoding from WSL on Windows
444+ output = output . force_encoding ( 'UTF-16LE' ) . encode ( 'UTF-8' , invalid : :replace , undef : :replace )
445+
446+ lines = output . lines . map ( &:strip ) . reject ( &:empty? )
447+
448+ # Find the header line (NAME STATE VERSION)
449+ header_index = lines . find_index { |line | line . match? ( /NAME.*STATE.*VERSION/i ) }
450+ return distributions unless header_index
451+
452+ # Parse distribution lines after the header
453+ lines [ ( header_index + 1 ) ..-1 ] . each do |line |
454+ # Remove default marker (*) and null bytes
455+ line = line . gsub ( /\* / , '' ) . gsub ( /\0 / , '' ) . strip
456+ next if line . empty?
457+
458+ # Split by whitespace and extract fields
459+ parts = line . split ( /\s +/ )
460+ next if parts . length < 3
461+
462+ distributions << {
463+ name : parts [ 0 ] ,
464+ state : parts [ 1 ] ,
465+ version : parts [ 2 ]
466+ }
467+ end
468+
469+ distributions
470+ end
427471 end
428472 end
429473end
0 commit comments