3131import hudson .FilePath ;
3232import hudson .Launcher ;
3333import hudson .model .Node ;
34+ import hudson .model .TaskListener ;
3435import hudson .util .ArgumentListBuilder ;
3536import hudson .util .VersionNumber ;
3637import java .io .BufferedReader ;
@@ -318,6 +319,12 @@ private LaunchResult launch(@NonNull EnvVars launchEnv, boolean quiet, FilePath
318319 return result ;
319320 }
320321
322+ private String executeCommand (String ... command ) throws IOException , InterruptedException {
323+ ByteArrayOutputStream output = new ByteArrayOutputStream ();
324+ launcher .launch ().cmds (command ).quiet (true ).stdout (output ).start ().joinWithTimeout (CLIENT_TIMEOUT , TimeUnit .SECONDS , launcher .getListener ());
325+ return output .toString (Charset .defaultCharset ()).trim ();
326+ }
327+
321328 /**
322329 * Who is executing this {@link DockerClient} instance.
323330 *
@@ -328,15 +335,28 @@ public String whoAmI() throws IOException, InterruptedException {
328335 // Windows does not support username
329336 return "" ;
330337 }
331- ByteArrayOutputStream userId = new ByteArrayOutputStream ();
332- launcher .launch ().cmds ("id" , "-u" ).quiet (true ).stdout (userId ).start ().joinWithTimeout (CLIENT_TIMEOUT , TimeUnit .SECONDS , launcher .getListener ());
333338
334- ByteArrayOutputStream groupId = new ByteArrayOutputStream ();
335- launcher .launch ().cmds ("id" , "-g" ).quiet (true ).stdout (groupId ).start ().joinWithTimeout (CLIENT_TIMEOUT , TimeUnit .SECONDS , launcher .getListener ());
339+ TaskListener listener = launcher .getListener ();
340+ final String rootlessId = "0:0" ;
341+ // First, check if under the hood it's Podman or Docker
342+ String engine = executeCommand ("docker" , "--version" );
343+ if (engine .toLowerCase ().contains ("podman" )) {
344+ listener .getLogger ().println ("Container engine is Podman with build in rootless mode" );
345+ return rootlessId ;
346+ }
347+ else {
348+ String rootless = executeCommand ("docker" , "info" , "-f" , "{{.SecurityOptions}}" );
349+ if (rootless .toLowerCase ().contains ("rootless" )) {
350+ listener .getLogger ().println ("Container engine is Docker with rootless mode" );
351+ return rootlessId ;
352+ }
353+ }
336354
337- final String charsetName = Charset .defaultCharset ().name ();
338- return String .format ("%s:%s" , userId .toString (charsetName ).trim (), groupId .toString (charsetName ).trim ());
355+ // Else not rootless, return the current user/group ids
356+ String userId = executeCommand ("id" , "-u" );
357+ String groupId = executeCommand ("id" , "-g" );
339358
359+ return String .format ("%s:%s" , userId , groupId );
340360 }
341361
342362 private static final Pattern hostnameMount = Pattern .compile ("/containers/([a-z0-9]{64})/hostname" );
0 commit comments