0

Problem

I want to start a MySQLContainer from a junit test with mvn clean verify. But for some reason it can't chown the container folder for my host user.

Here is a screenshot that illustrates the problem:

org.testcontainers.containers.ContainerLaunchException: Container startup failed for image mysql:8.0.33 at com.xyzcorp.StudentServiceCopyTest.testMySQL8(StudentServiceCopyTest.java:61) Caused by: org.rnorth.ducttape.RetryCountExceededException: Retry limit hit with exception at com.xyzcorp.StudentServiceCopyTest.testMySQL8(StudentServiceCopyTest.java:61) Caused by: org.testcontainers.containers.ContainerLaunchException: Could not create/start container at com.xyzcorp.StudentServiceCopyTest.testMySQL8(StudentServiceCopyTest.java:61) Caused by: com.github.dockerjava.api.exception.InternalServerErrorException: Status 500: {"cause":"error during bulk transfer for copier.request{Request:\"PUT\", Root:\"/\", preservedRoot:\"/home/jvanmont/.local/share/containers/storage/overlay/297e95cb55db40d82aa6e025772f7e05a009d64f5563ac3421e34592209e8627/merged\", rootPrefix:\"/home/jvanmont/.local/share/containers/storage/overlay/297e95cb55db40d82aa6e025772f7e05a009d64f5563ac3421e34592209e8627/merged\", Directory:\"/\", preservedDirectory:\"/home/jvanmont/.local/share/containers/storage/overlay/297e95cb55db40d82aa6e025772f7e05a009d64f5563ac3421e34592209e8627/merged\", Globs:[]string{}, preservedGlobs:[]string{}, StatOptions:copier.StatOptions{CheckForArchives:false, Excludes:[]string(nil)}, GetOptions:copier.GetOptions{UIDMap:[]idtools.IDMap(nil), GIDMap:[]idtools.IDMap(nil), Excludes:[]string(nil), ExpandArchives:false, ChownDirs:(*idtools.IDPair)(nil), ChmodDirs:(*fs.FileMode)(nil), ChownFiles:(*idtools.IDPair)(nil), ChmodFiles:(*fs.FileMode)(nil), StripSetuidBit:false, StripSetgidBit:false, StripStickyBit:false, StripXattrs:false, KeepDirectoryNames:false, Rename:map[string]string(nil), NoDerefSymlinks:false, IgnoreUnreadable:false, NoCrossDevice:false}, PutOptions:copier.PutOptions{UIDMap:[]idtools.IDMap(nil), GIDMap:[]idtools.IDMap(nil), DefaultDirOwner:(*idtools.IDPair)(nil), DefaultDirMode:(*fs.FileMode)(nil), ChownDirs:(*idtools.IDPair)(nil), ChmodDirs:(*fs.FileMode)(nil), ChownFiles:(*idtools.IDPair)(nil), ChmodFiles:(*fs.FileMode)(nil), StripSetuidBit:false, StripSetgidBit:false, StripStickyBit:false, StripXattrs:false, IgnoreXattrErrors:false, IgnoreDevices:false, NoOverwriteDirNonDir:false, NoOverwriteNonDirDir:false, Rename:map[string]string(nil)}, MkdirOptions:copier.MkdirOptions{UIDMap:[]idtools.IDMap(nil), GIDMap:[]idtools.IDMap(nil), ChownNew:(*idtools.IDPair)(nil), ChmodNew:(*fs.FileMode)(nil)}, RemoveOptions:copier.RemoveOptions{All:false}}: copier: put: error setting ownership of \"/etc/mysql/conf.d\" to 1980042590:1980042590: lchown /etc/mysql/conf.d: invalid argument","message":"error during bulk transfer for copier.request{Request:\"PUT\", Root:\"/\", preservedRoot:\"/home/jvanmont/.local/share/containers/storage/overlay/297e95cb55db40d82aa6e025772f7e05a009d64f5563ac3421e34592209e8627/merged\", rootPrefix:\"/home/jvanmont/.local/share/containers/storage/overlay/297e95cb55db40d82aa6e025772f7e05a009d64f5563ac3421e34592209e8627/merged\", Directory:\"/\", preservedDirectory:\"/home/jvanmont/.local/share/containers/storage/overlay/297e95cb55db40d82aa6e025772f7e05a009d64f5563ac3421e34592209e8627/merged\", Globs:[]string{}, preservedGlobs:[]string{}, StatOptions:copier.StatOptions{CheckForArchives:false, Excludes:[]string(nil)}, GetOptions:copier.GetOptions{UIDMap:[]idtools.IDMap(nil), GIDMap:[]idtools.IDMap(nil), Excludes:[]string(nil), ExpandArchives:false, ChownDirs:(*idtools.IDPair)(nil), ChmodDirs:(*fs.FileMode)(nil), ChownFiles:(*idtools.IDPair)(nil), ChmodFiles:(*fs.FileMode)(nil), StripSetuidBit:false, StripSetgidBit:false, StripStickyBit:false, StripXattrs:false, KeepDirectoryNames:false, Rename:map[string]string(nil), NoDerefSymlinks:false, IgnoreUnreadable:false, NoCrossDevice:false}, PutOptions:copier.PutOptions{UIDMap:[]idtools.IDMap(nil), GIDMap:[]idtools.IDMap(nil), DefaultDirOwner:(*idtools.IDPair)(nil), DefaultDirMode:(*fs.FileMode)(nil), ChownDirs:(*idtools.IDPair)(nil), ChmodDirs:(*fs.FileMode)(nil), ChownFiles:(*idtools.IDPair)(nil), ChmodFiles:(*fs.FileMode)(nil), StripSetuidBit:false, StripSetgidBit:false, StripStickyBit:false, StripXattrs:false, IgnoreXattrErrors:false, IgnoreDevices:false, NoOverwriteDirNonDir:false, NoOverwriteNonDirDir:false, Rename:map[string]string(nil)}, MkdirOptions:copier.MkdirOptions{UIDMap:[]idtools.IDMap(nil), GIDMap:[]idtools.IDMap(nil), ChownNew:(*idtools.IDPair)(nil), ChmodNew:(*fs.FileMode)(nil)}, RemoveOptions:copier.RemoveOptions{All:false}}: copier: put: error setting ownership of \"/etc/mysql/conf.d\" to 1980042590:1980042590: lchown /etc/mysql/conf.d: invalid argument","response":500}

What I've tried

This is the most simplified version of my code that I've been able to get, which still produces the problem I described above.

    @Test
    public void testMySQL8() throws SQLException {
        assumeFalse(SystemUtils.IS_OS_WINDOWS);
        MySQLContainer container = new MySQLContainer<>("mysql:8.0.33")
                .withCreateContainerCmdModifier(cmd -> cmd.withUser("0:0").withCmd("--user 0:0"))
                 /*.withCopyFileToContainer(MountableFile.forClasspathResource(
                 "db/testMySQL.cnf"), "/home")
                 * .withUsername("jvanmont")
                 .withInitScript("db/init_mysql.sql").withPrivilegedMode(true).withUsername("test")
                 .withCommand("mysqld --default-authentication-plugin=mysql_native_password")*/;
        container.start();
        try {
            ResultSet resultSet = performQuery(container, "SELECT VERSION()");
            resultSet.next();
            String resultSetString = resultSet.getString(1);
            System.out.println("mySQL version: " + resultSetString);

            assertTrue("The database version can be set using a container rule parameter",
                    "8.0.33".equals(resultSetString));
        } finally {
            container.stop();
        }
    }

    <dependency>
        <groupId>org.testcontainers</groupId>
        <artifactId>testcontainers</artifactId>
        <version>1.18.3</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.testcontainers</groupId>
        <artifactId>junit-jupiter</artifactId>
        <version>1.18.3</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.testcontainers</groupId>
        <artifactId>mysql</artifactId>
        <version>1.18.3</version>
        <scope>test</scope>
    </dependency>
    
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.33</version>
    </dependency>

   bash-4.4$ podman -v
   podman version 4.2.0

   Java 17
   mvn -v 3.8.8

   bash-4.4$ uname -a
   Linux hbidev** 4.18.0-425.19.2.el8_7.x86_64 #1 SMP Tue Apr 4 22:38:11 UTC 2023 
   x86_64 x86_64 x86_64 GNU/Linux

My Research

I can run the code with sudo. I can run the container with podman run ...

No success: Podman is running rootless with host-user. Podman socket is owned by hos-user. I tried also with SELinux permissive mode.

What I tried from inside the testcontainer code -> I tried passing root user 0:0 when starting the container. I tried to start the container in privileged mode.

I turned on testcontainer DEBUG:

Cmd: org.testcontainers.shaded.com.github.dockerjava.core.command.CopyArchiveToContainerCmdImpl@62ce72ff[cp ,-a=false ,<null>, ,d430a1a20b47ebd457358549a57bb762ea59bf7a9831110390bc2a7dafcc3ad8,:,/]

Following is my podman id-mapping:

bash-4.4$ podman info | grep id
    idlePercent: 98.81
  hostname: hbidev**
  idMappings:
    gidmap:
    - container_id: 0
      host_id: 1980042590
    - container_id: 1
      host_id: 100000
    uidmap:
    - container_id: 0
      host_id: 1980042590
    - container_id: 1
      host_id: 100000
  - bridge

Question

Why testcontainer tries to chown the conf.d folder? Why are all folders inside the container owned by root/nobody?

How can start the container as root from a testcontainer so it doesn't have to chown the folders inside the container for my host-user.

Jo Vanmont
  • 41
  • 4

0 Answers0