@@ -111,6 +111,7 @@ fn container_id_from_cgroup_v2(mount_info: impl AsRef<Path>) -> Result<String> {
111111#[ derive( Debug , Copy , Clone , PartialEq , Eq ) ]
112112enum RuntimeKind {
113113 Auto ,
114+ AppleContainer ,
114115 Docker ,
115116 Podman ,
116117}
@@ -120,6 +121,7 @@ impl FromStr for RuntimeKind {
120121
121122 fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
122123 match s. to_ascii_lowercase ( ) . as_str ( ) {
124+ "container" => Ok ( RuntimeKind :: AppleContainer ) ,
123125 "docker" => Ok ( RuntimeKind :: Docker ) ,
124126 "podman" => Ok ( RuntimeKind :: Podman ) ,
125127 "auto" => Ok ( RuntimeKind :: Auto ) ,
@@ -139,6 +141,7 @@ struct Mount {
139141impl RuntimeKind {
140142 fn cmd ( & self ) -> & str {
141143 match self {
144+ RuntimeKind :: AppleContainer => "container" ,
142145 RuntimeKind :: Docker => "docker" ,
143146 RuntimeKind :: Podman => "podman" ,
144147 RuntimeKind :: Auto => unreachable ! ( "Auto should be resolved before use" ) ,
@@ -148,6 +151,7 @@ impl RuntimeKind {
148151 /// Detect if the current runtime is rootless.
149152 fn detect_rootless ( self ) -> Result < bool > {
150153 match self {
154+ RuntimeKind :: AppleContainer => Ok ( false ) ,
151155 RuntimeKind :: Docker => {
152156 let output = Command :: new ( self . cmd ( ) )
153157 . arg ( "info" )
@@ -206,14 +210,16 @@ struct ContainerRuntimeInfo {
206210impl ContainerRuntimeInfo {
207211 /// Detect container runtime provider, prioritise docker over podman if
208212 /// both are on the path, unless `PREK_CONTAINER_RUNTIME` is set to override detection.
209- fn resolve_runtime_kind < DF , PF > (
213+ fn resolve_runtime_kind < DF , PF , CF > (
210214 env_override : Option < String > ,
211215 docker_available : DF ,
212216 podman_available : PF ,
217+ apple_container_available : CF ,
213218 ) -> RuntimeKind
214219 where
215220 DF : Fn ( ) -> bool ,
216221 PF : Fn ( ) -> bool ,
222+ CF : Fn ( ) -> bool ,
217223 {
218224 if let Some ( val) = env_override {
219225 match RuntimeKind :: from_str ( & val) {
@@ -243,6 +249,9 @@ impl ContainerRuntimeInfo {
243249 if podman_available ( ) {
244250 return RuntimeKind :: Podman ;
245251 }
252+ if apple_container_available ( ) {
253+ return RuntimeKind :: AppleContainer ;
254+ }
246255
247256 debug ! ( "No container runtime found on PATH, defaulting to docker" ) ;
248257 RuntimeKind :: Docker
@@ -253,6 +262,7 @@ impl ContainerRuntimeInfo {
253262 EnvVars :: var ( EnvVars :: PREK_CONTAINER_RUNTIME ) . ok ( ) ,
254263 || which:: which ( "docker" ) . is_ok ( ) ,
255264 || which:: which ( "podman" ) . is_ok ( ) ,
265+ || which:: which ( "container" ) . is_ok ( ) ,
256266 ) ;
257267 let rootless = runtime. detect_rootless ( ) . unwrap_or_else ( |e| {
258268 warn ! ( "Failed to detect if container runtime is rootless: {e}, defaulting to rootful" ) ;
@@ -283,6 +293,10 @@ impl ContainerRuntimeInfo {
283293 self . runtime == RuntimeKind :: Podman
284294 }
285295
296+ fn is_apple_container ( & self ) -> bool {
297+ self . runtime == RuntimeKind :: AppleContainer
298+ }
299+
286300 /// Get the path of the current directory in the host.
287301 fn map_to_host_path < ' a > ( & self , path : & ' a Path ) -> Cow < ' a , Path > {
288302 for mount in & self . mounts {
@@ -387,14 +401,21 @@ impl Docker {
387401 }
388402
389403 let work_dir = CONTAINER_RUNTIME . map_to_host_path ( work_dir) ;
404+ let z = if CONTAINER_RUNTIME . is_apple_container ( ) {
405+ "" // Not currently supported
406+ } else {
407+ ",Z"
408+ } ;
409+ if !CONTAINER_RUNTIME . is_apple_container ( ) {
410+ // Run an init inside the container that forwards signals and reaps processes
411+ command. arg ( "--init" ) ;
412+ }
390413 command
391- // https://docs.docker.com/engine/ reference/commandline/ run/#mount-volumes-from-container- volumes-from
414+ // https://docs.docker.com/reference/cli/docker/container/ run/#volumes-from
392415 // The `Z` option tells Docker to label the content with a private
393416 // unshared label. Only the current container can use a private volume.
394417 . arg ( "--volume" )
395- . arg ( format ! ( "{}:/src:rw,Z" , work_dir. display( ) ) )
396- // Run an init inside the container that forwards signals and reaps processes
397- . arg ( "--init" )
418+ . arg ( format ! ( "{}:/src:rw{}" , work_dir. display( ) , z) )
398419 . arg ( "--workdir" )
399420 . arg ( "/src" ) ;
400421
@@ -673,52 +694,72 @@ mod tests {
673694 env_override : Option < & str > ,
674695 docker_available : bool ,
675696 podman_available : bool ,
697+ apple_container_available : bool ,
676698 ) -> RuntimeKind {
677699 ContainerRuntimeInfo :: resolve_runtime_kind (
678700 env_override. map ( ToString :: to_string) ,
679701 || docker_available,
680702 || podman_available,
703+ || apple_container_available,
681704 )
682705 }
683706
684- assert_eq ! ( runtime_with( None , true , false ) , RuntimeKind :: Docker ) ;
685- assert_eq ! ( runtime_with( None , false , true ) , RuntimeKind :: Podman ) ;
686- assert_eq ! ( runtime_with( None , false , false ) , RuntimeKind :: Docker ) ;
707+ assert_eq ! ( runtime_with( None , true , false , false ) , RuntimeKind :: Docker ) ;
708+ assert_eq ! ( runtime_with( None , false , true , false ) , RuntimeKind :: Podman ) ;
709+ assert_eq ! (
710+ runtime_with( None , false , false , true ) ,
711+ RuntimeKind :: AppleContainer
712+ ) ;
713+ assert_eq ! ( runtime_with( None , false , false , false ) , RuntimeKind :: Docker ) ;
687714
688- assert_eq ! ( runtime_with( Some ( "auto" ) , true , false ) , RuntimeKind :: Docker ) ;
689- assert_eq ! ( runtime_with( Some ( "auto" ) , false , true ) , RuntimeKind :: Podman ) ;
690715 assert_eq ! (
691- runtime_with( Some ( "auto" ) , false , false ) ,
716+ runtime_with( Some ( "auto" ) , true , false , false ) ,
717+ RuntimeKind :: Docker
718+ ) ;
719+ assert_eq ! (
720+ runtime_with( Some ( "auto" ) , false , true , false ) ,
721+ RuntimeKind :: Podman
722+ ) ;
723+ assert_eq ! (
724+ runtime_with( Some ( "auto" ) , false , false , true ) ,
725+ RuntimeKind :: AppleContainer
726+ ) ;
727+ assert_eq ! (
728+ runtime_with( Some ( "auto" ) , false , false , false ) ,
692729 RuntimeKind :: Docker
693730 ) ;
694731
695732 assert_eq ! (
696- runtime_with( Some ( "docker" ) , true , false ) ,
733+ runtime_with( Some ( "docker" ) , true , false , false ) ,
697734 RuntimeKind :: Docker
698735 ) ;
699736 assert_eq ! (
700- runtime_with( Some ( "docker" ) , false , true ) ,
737+ runtime_with( Some ( "docker" ) , false , true , false ) ,
701738 RuntimeKind :: Docker
702739 ) ;
703740 assert_eq ! (
704- runtime_with( Some ( "DOCKER" ) , false , false ) ,
741+ runtime_with( Some ( "DOCKER" ) , false , false , false ) ,
705742 RuntimeKind :: Docker
706743 ) ;
707744 assert_eq ! (
708- runtime_with( Some ( "podman" ) , true , false ) ,
745+ runtime_with( Some ( "podman" ) , true , false , false ) ,
709746 RuntimeKind :: Podman
710747 ) ;
711748 assert_eq ! (
712- runtime_with( Some ( "podman" ) , false , true ) ,
749+ runtime_with( Some ( "podman" ) , false , true , false ) ,
713750 RuntimeKind :: Podman
714751 ) ;
715752 assert_eq ! (
716- runtime_with( Some ( "podman" ) , false , false ) ,
753+ runtime_with( Some ( "podman" ) , false , false , false ) ,
717754 RuntimeKind :: Podman
718755 ) ;
756+ assert_eq ! (
757+ runtime_with( Some ( "container" ) , true , true , false ) ,
758+ RuntimeKind :: AppleContainer
759+ ) ;
719760
720761 assert_eq ! (
721- runtime_with( Some ( "invalid" ) , false , false ) ,
762+ runtime_with( Some ( "invalid" ) , false , false , false ) ,
722763 RuntimeKind :: Docker
723764 ) ;
724765 }
0 commit comments