|
4 | 4 | import com.github.dockerjava.api.command.CreateContainerResponse; |
5 | 5 | import com.github.dockerjava.api.exception.NotFoundException; |
6 | 6 | import com.github.dockerjava.core.util.CompressArchiveUtil; |
| 7 | +import com.github.dockerjava.utils.LogContainerTestCallback; |
7 | 8 | import org.apache.commons.io.FileUtils; |
8 | 9 | import org.junit.Test; |
9 | 10 | import org.slf4j.Logger; |
|
14 | 15 | import java.nio.file.Files; |
15 | 16 | import java.nio.file.Path; |
16 | 17 | import java.nio.file.Paths; |
| 18 | +import java.util.concurrent.TimeUnit; |
17 | 19 |
|
18 | 20 | import static org.hamcrest.MatcherAssert.assertThat; |
| 21 | +import static org.hamcrest.Matchers.containsString; |
19 | 22 | import static org.hamcrest.Matchers.equalTo; |
20 | 23 | import static org.hamcrest.Matchers.isEmptyOrNullString; |
21 | 24 | import static org.hamcrest.Matchers.not; |
| 25 | +import static org.hamcrest.Matchers.notNullValue; |
22 | 26 | import static org.junit.Assert.assertTrue; |
| 27 | +import static org.junit.Assume.assumeThat; |
23 | 28 |
|
24 | 29 | public class CopyArchiveToContainerCmdIT extends CmdIT { |
25 | 30 | public static final Logger LOG = LoggerFactory.getLogger(CopyArchiveToContainerCmdIT.class); |
@@ -143,4 +148,71 @@ public void copyFileWithExecutePermission() throws Exception { |
143 | 148 | assertThat(exitCode, equalTo(0)); |
144 | 149 | } |
145 | 150 |
|
| 151 | + @Test |
| 152 | + public void copyFileWithUIDGID() throws Exception { |
| 153 | + Path with = Files.createFile(Files.createTempDirectory("copyFileWithUIDGID").resolve("uidgid.with")); |
| 154 | + Files.write(with, "with".getBytes()); |
| 155 | + |
| 156 | + Path without = Files.createFile(Files.createTempDirectory("copyFileWithUIDGID").resolve("uidgid.without")); |
| 157 | + Files.write(without, "without".getBytes()); |
| 158 | + |
| 159 | + String containerCmd = "while [ ! -f /home/uidgid.with ]; do true; done && stat -c %n:%u /home/uidgid.with /home/uidgid.without"; |
| 160 | + Long syncUserUid = 4L; // sync user in busybox uses uid=4 |
| 161 | + CreateContainerResponse container = dockerRule.getClient().createContainerCmd("busybox") |
| 162 | + .withName("copyFileWithUIDGID") |
| 163 | + .withCmd("/bin/sh", "-c", containerCmd) |
| 164 | + .withUser(syncUserUid.toString()) |
| 165 | + .exec(); |
| 166 | + // start the container |
| 167 | + dockerRule.getClient().startContainerCmd(container.getId()).exec(); |
| 168 | + |
| 169 | + dockerRule.getClient().copyArchiveToContainerCmd(container.getId()) |
| 170 | + .withRemotePath("/home/") |
| 171 | + .withHostResource(without.toString()) |
| 172 | + .withCopyUIDGID(false) |
| 173 | + .exec(); |
| 174 | + dockerRule.getClient().copyArchiveToContainerCmd(container.getId()) |
| 175 | + .withRemotePath("/home/") |
| 176 | + .withHostResource(with.toString()) |
| 177 | + .withCopyUIDGID(true) |
| 178 | + .exec(); |
| 179 | + |
| 180 | + // await exit code |
| 181 | + int exitCode = dockerRule.getClient().waitContainerCmd(container.getId()) |
| 182 | + .start() |
| 183 | + .awaitStatusCode(); |
| 184 | + // check result |
| 185 | + assertThat(exitCode, equalTo(0)); |
| 186 | + |
| 187 | + LogContainerTestCallback loggingCallback = new LogContainerTestCallback(true); |
| 188 | + |
| 189 | + dockerRule.getClient().logContainerCmd(container.getId()) |
| 190 | + .withStdOut(true) |
| 191 | + .withTailAll() |
| 192 | + .exec(loggingCallback); |
| 193 | + |
| 194 | + loggingCallback.awaitCompletion(3, TimeUnit.SECONDS); |
| 195 | + String containerOutput = loggingCallback.toString(); |
| 196 | + |
| 197 | + assertThat(containerOutput, containsString(String.format("/home/uidgid.with:%d", syncUserUid))); |
| 198 | + |
| 199 | + Long hostUid = getHostUidIfPossible(); |
| 200 | + assumeThat("could not get the uid on host platform", hostUid, notNullValue(Long.class)); |
| 201 | + assertThat(containerOutput, containsString(String.format("/home/uidgid.without:%d", hostUid))); |
| 202 | + } |
| 203 | + |
| 204 | + private static Long getHostUidIfPossible() { |
| 205 | + try { |
| 206 | + Class<?> unixSystemClazz = Class.forName("com.sun.security.auth.module.UnixSystem"); |
| 207 | + Object unixSystem = unixSystemClazz.newInstance(); |
| 208 | + Object uid = unixSystemClazz.getMethod("getUid").invoke(unixSystem); |
| 209 | + if (uid == null) { |
| 210 | + return null; |
| 211 | + } |
| 212 | + |
| 213 | + return uid instanceof Long ? (Long) uid : Long.parseLong(uid.toString()); |
| 214 | + } catch (Exception e) { |
| 215 | + return null; |
| 216 | + } |
| 217 | + } |
146 | 218 | } |
0 commit comments