77import { createContainerProperties , startEventSeen , ResolverResult , getTunnelInformation , getDockerfilePath , getDockerContextPath , DockerResolverParameters , isDockerFileConfig , uriToWSLFsPath , WorkspaceConfiguration , getFolderImageName , inspectDockerImage , logUMask , SubstitutedConfig , checkDockerSupportForGPU , isBuildKitImagePolicyError , isBuildxCacheToInline } from './utils' ;
88import { ContainerProperties , setupInContainer , ResolverProgress , ResolverParameters } from '../spec-common/injectHeadless' ;
99import { ContainerError , toErrorText } from '../spec-common/errors' ;
10- import { ContainerDetails , listContainers , DockerCLIParameters , inspectContainers , dockerCLI , dockerPtyCLI , toPtyExecParameters , ImageDetails , toExecParameters , removeContainer } from '../spec-shutdown/dockerUtils' ;
10+ import { ContainerDetails , listContainers , DockerCLIParameters , inspectContainers , dockerCLI , dockerPtyCLI , toPtyExecParameters , ImageDetails , toExecParameters , removeContainer , CLIVariant } from '../spec-shutdown/dockerUtils' ;
1111import { DevContainerConfig , DevContainerFromDockerfileConfig , DevContainerFromImageConfig } from '../spec-configuration/configuration' ;
1212import { LogLevel , Log , makeLog } from '../spec-utils/log' ;
1313import { extendImage , getExtendImageBuildInfo , updateRemoteUserUID } from './containerFeatures' ;
@@ -347,8 +347,8 @@ export async function spawnDevContainer(params: DockerResolverParameters, config
347347 const exposedPorts = typeof appPort === 'number' || typeof appPort === 'string' ? [ appPort ] : appPort || [ ] ;
348348 const exposed = ( < string [ ] > [ ] ) . concat ( ...exposedPorts . map ( port => [ '-p' , typeof port === 'number' ? `127.0.0.1:${ port } :${ port } ` : port ] ) ) ;
349349
350- const cwdMount = workspaceMount ? [ '--mount' , workspaceMount ] : [ ] ;
351- const additionalMount = additionalMountString ? [ '--mount' , additionalMountString ] : [ ] ;
350+ const cwdMount = workspaceMount ? ( params . cliVariant === CLIVariant . Wslc ? convertMountToVolume ( workspaceMount ) : [ '--mount' , workspaceMount ] ) : [ ] ;
351+ const additionalMount = additionalMountString ? ( params . cliVariant === CLIVariant . Wslc ? convertMountToVolume ( additionalMountString ) : [ '--mount' , additionalMountString ] ) : [ ] ;
352352
353353 const envObj = mergedConfig . containerEnv || { } ;
354354 const containerEnv = Object . keys ( envObj )
@@ -360,24 +360,30 @@ export async function spawnDevContainer(params: DockerResolverParameters, config
360360 const containerUserArgs = containerUser ? [ '-u' , containerUser ] : [ ] ;
361361
362362 const featureArgs : string [ ] = [ ] ;
363- if ( mergedConfig . init ) {
364- featureArgs . push ( '--init' ) ;
365- }
366- if ( mergedConfig . privileged ) {
367- featureArgs . push ( '--privileged' ) ;
368- }
369- for ( const cap of mergedConfig . capAdd || [ ] ) {
370- featureArgs . push ( '--cap-add' , cap ) ;
371- }
372- for ( const securityOpt of mergedConfig . securityOpt || [ ] ) {
373- featureArgs . push ( '--security-opt' , securityOpt ) ;
363+ // wslc does not support --init, --privileged, --cap-add, or --security-opt
364+ if ( params . cliVariant !== CLIVariant . Wslc ) {
365+ if ( mergedConfig . init ) {
366+ featureArgs . push ( '--init' ) ;
367+ }
368+ if ( mergedConfig . privileged ) {
369+ featureArgs . push ( '--privileged' ) ;
370+ }
371+ for ( const cap of mergedConfig . capAdd || [ ] ) {
372+ featureArgs . push ( '--cap-add' , cap ) ;
373+ }
374+ for ( const securityOpt of mergedConfig . securityOpt || [ ] ) {
375+ featureArgs . push ( '--security-opt' , securityOpt ) ;
376+ }
374377 }
375378
376379 const featureMounts = ( [ ] as string [ ] ) . concat (
377380 ...[
378381 ...mergedConfig . mounts || [ ] ,
379382 ...params . additionalMounts ,
380- ] . map ( m => generateMountCommand ( m ) )
383+ ] . map ( m => {
384+ const mountArgs = generateMountCommand ( m ) ;
385+ return params . cliVariant === CLIVariant . Wslc ? convertMountArgsToVolume ( mountArgs ) : mountArgs ;
386+ } )
381387 ) ;
382388
383389 const customEntrypoints = mergedConfig . entrypoints || [ ] ;
@@ -396,9 +402,7 @@ while sleep 1 & wait $!; do :; done`, '-']; // `wait $!` allows for the `trap` t
396402
397403 const args = [
398404 'run' ,
399- '--sig-proxy=false' ,
400- '-a' , 'STDOUT' ,
401- '-a' , 'STDERR' ,
405+ ...( params . cliVariant === CLIVariant . Wslc ? [ ] : [ '--sig-proxy=false' , '-a' , 'STDOUT' , '-a' , 'STDERR' ] ) ,
402406 ...exposed ,
403407 ...cwdMount ,
404408 ...additionalMount ,
@@ -432,7 +436,7 @@ while sleep 1 & wait $!; do :; done`, '-']; // `wait $!` allows for the `trap` t
432436}
433437
434438async function getPodmanArgs ( params : DockerResolverParameters , config : DevContainerFromDockerfileConfig | DevContainerFromImageConfig , mergedConfig : MergedDevContainerConfig , imageDetails : ( ) => Promise < ImageDetails > ) : Promise < string [ ] > {
435- if ( params . isPodman && params . common . cliHost . platform === 'linux' ) {
439+ if ( params . cliVariant === CLIVariant . Podman && params . common . cliHost . platform === 'linux' ) {
436440 const args = [ '--security-opt' , 'label=disable' ] ;
437441 const hasIdMapping = ( config . runArgs || [ ] ) . some ( arg => / - - [ u g ] i d m a p ( = | $ ) / . test ( arg ) ) ;
438442 if ( ! hasIdMapping ) {
@@ -446,6 +450,32 @@ async function getPodmanArgs(params: DockerResolverParameters, config: DevContai
446450 return [ ] ;
447451}
448452
453+ // Convert a --mount string (e.g., "type=bind,source=/a,target=/b,consistency=cached") to -v syntax for wslc.
454+ function convertMountToVolume ( mountStr : string ) : string [ ] {
455+ const parts = new Map ( mountStr . split ( ',' ) . map ( p => {
456+ const eq = p . indexOf ( '=' ) ;
457+ return eq === - 1 ? [ p , '' ] : [ p . substring ( 0 , eq ) , p . substring ( eq + 1 ) ] ;
458+ } ) ) ;
459+ const source = parts . get ( 'source' ) || parts . get ( 'src' ) || '' ;
460+ const target = parts . get ( 'target' ) || parts . get ( 'dst' ) || parts . get ( 'destination' ) || '' ;
461+ if ( source && target ) {
462+ return [ '-v' , `${ source } :${ target } ` ] ;
463+ }
464+ if ( target ) {
465+ return [ '-v' , target ] ;
466+ }
467+ // Fallback: pass as --mount and let the runtime handle it.
468+ return [ '--mount' , mountStr ] ;
469+ }
470+
471+ // Convert --mount args array (e.g., ['--mount', 'type=bind,...']) to -v syntax for wslc.
472+ function convertMountArgsToVolume ( args : string [ ] ) : string [ ] {
473+ if ( args . length === 2 && args [ 0 ] === '--mount' ) {
474+ return convertMountToVolume ( args [ 1 ] ) ;
475+ }
476+ return args ;
477+ }
478+
449479function getLabels ( labels : string [ ] ) : string [ ] {
450480 let result : string [ ] = [ ] ;
451481 labels . forEach ( each => result . push ( '-l' , each ) ) ;
0 commit comments